diff --git a/hive/db/sql_scripts/condenser_follows.sql b/hive/db/sql_scripts/condenser_follows.sql index 52237835e7c00c0d11406be0592360e6460a9c65..fbfa033f28006311dca9c04c508d6e21a2d61994 100644 --- a/hive/db/sql_scripts/condenser_follows.sql +++ b/hive/db/sql_scripts/condenser_follows.sql @@ -13,3 +13,59 @@ BEGIN END $function$ language plpgsql STABLE; + +DROP FUNCTION IF EXISTS condenser_get_followers; +-- list of account names that follow/ignore given account +CREATE FUNCTION condenser_get_followers( in _account VARCHAR, in _start VARCHAR, in _type INT, in _limit INT ) +RETURNS SETOF hive_accounts.name%TYPE +AS +$function$ +DECLARE + __account_id INT; + __start_id INT; +BEGIN + __account_id = find_account_id( _account, True ); + __start_id = find_account_id( _start, _start <> '' ); + IF __start_id <> 0 THEN + SELECT INTO __start_id COALESCE( ( SELECT id FROM hive_follows WHERE following = __account_id AND follower = __start_id ), 0 ); + END IF; + RETURN QUERY SELECT + ha.name + FROM + hive_follows hf + JOIN hive_accounts ha ON hf.follower = ha.id + WHERE + hf.following = __account_id AND hf.state = _type AND ( __start_id = 0 OR hf.id < __start_id ) + ORDER BY hf.id DESC + LIMIT _limit; +END +$function$ +language plpgsql STABLE; + +DROP FUNCTION IF EXISTS condenser_get_following; +-- list of account names followed/ignored by given account +CREATE FUNCTION condenser_get_following( in _account VARCHAR, in _start VARCHAR, in _type INT, in _limit INT ) +RETURNS SETOF hive_accounts.name%TYPE +AS +$function$ +DECLARE + __account_id INT; + __start_id INT; +BEGIN + __account_id = find_account_id( _account, True ); + __start_id = find_account_id( _start, _start <> '' ); + IF __start_id <> 0 THEN + SELECT INTO __start_id COALESCE( ( SELECT id FROM hive_follows WHERE follower = __account_id AND following = __start_id ), 0 ); + END IF; + RETURN QUERY SELECT + ha.name + FROM + hive_follows hf + JOIN hive_accounts ha ON hf.following = ha.id + WHERE + hf.follower = __account_id AND hf.state = _type AND ( __start_id = 0 OR hf.id < __start_id ) + ORDER BY hf.id DESC + LIMIT _limit; +END +$function$ +language plpgsql STABLE; diff --git a/hive/server/common/helpers.py b/hive/server/common/helpers.py index 632886c0776d2394d63757851b938ab1fed03c21..dba7b65ad5583a61667513dfe05ed0ce39ff9920 100644 --- a/hive/server/common/helpers.py +++ b/hive/server/common/helpers.py @@ -155,8 +155,10 @@ def valid_offset(offset, ubound=None): def valid_follow_type(follow_type: str): """Ensure follow type is valid steemd type.""" - assert follow_type in ['blog', 'ignore'], 'invalid follow_type `%s`' % follow_type - return follow_type + # ABW: should be extended with blacklists etc. (and those should be implemented as next 'state' values) + supported_follow_types = dict(blog=1, ignore=2) + assert follow_type in supported_follow_types, "Unsupported follow type, valid types: {}".format(", ".join(supported_follow_types.keys())) + return supported_follow_types[follow_type] def valid_date(date, allow_empty=False): """ Ensure that date is in correct format """ diff --git a/hive/server/condenser_api/cursor.py b/hive/server/condenser_api/cursor.py index 5a69fdb12ccd0cddd9f861a5d90d5dbc672c0eb2..eaf82608072aa1c4f4deb63460ef7b88addce8fb 100644 --- a/hive/server/condenser_api/cursor.py +++ b/hive/server/condenser_api/cursor.py @@ -41,56 +41,15 @@ async def _get_account_id(db, name): return _id -async def get_followers(db, account: str, start: str, follow_type: str, limit: int): +async def get_followers(db, account: str, start: str, state: int, limit: int): """Get a list of accounts following a given account.""" - account_id = await _get_account_id(db, account) - start_id = await _get_account_id(db, start) if start else None - state = 2 if follow_type == 'ignore' else 1 - - seek = '' - if start_id: - seek = """AND hf.created_at <= ( - SELECT created_at FROM hive_follows - WHERE following = :account_id - AND follower = :start_id)""" - - sql = """ - SELECT name FROM hive_follows hf - LEFT JOIN hive_accounts ha ON hf.follower = ha.id - WHERE hf.following = :account_id - AND state = :state %s - ORDER BY hf.created_at DESC - LIMIT :limit - """ % seek - - return await db.query_col(sql, account_id=account_id, start_id=start_id, - state=state, limit=limit) - + sql = "SELECT * FROM condenser_get_followers( (:account)::VARCHAR, (:start)::VARCHAR, :type, :limit )" + return await db.query_col(sql, account=account, start=start, type=state, limit=limit) -async def get_following(db, account: str, start: str, follow_type: str, limit: int): +async def get_following(db, account: str, start: str, state: int, limit: int): """Get a list of accounts followed by a given account.""" - account_id = await _get_account_id(db, account) - start_id = await _get_account_id(db, start) if start else None - state = 2 if follow_type == 'ignore' else 1 - - seek = '' - if start_id: - seek = """AND hf.created_at <= ( - SELECT created_at FROM hive_follows - WHERE follower = :account_id - AND following = :start_id)""" - - sql = """ - SELECT name FROM hive_follows hf - LEFT JOIN hive_accounts ha ON hf.following = ha.id - WHERE hf.follower = :account_id - AND state = :state %s - ORDER BY hf.created_at DESC - LIMIT :limit - """ % seek - - return await db.query_col(sql, account_id=account_id, start_id=start_id, - state=state, limit=limit) + sql = "SELECT * FROM condenser_get_following( (:account)::VARCHAR, (:start)::VARCHAR, :type, :limit )" + return await db.query_col(sql, account=account, start=start, type=state, limit=limit) async def get_reblogged_by(db, author: str, permlink: str): diff --git a/hive/server/condenser_api/methods.py b/hive/server/condenser_api/methods.py index 43659cf9f9383885b210335f9d12e2b472d2882d..03c4fb143db3366d63be9fa6d8c996cecaba4269 100644 --- a/hive/server/condenser_api/methods.py +++ b/hive/server/condenser_api/methods.py @@ -79,8 +79,8 @@ def _legacy_follower(follower, following, follow_type): return dict(follower=follower, following=following, what=[follow_type]) @return_error_info -async def get_followers(context, account: str, start: str, follow_type: str = None, - limit: int = None, **kwargs): +async def get_followers(context, account: str, start: str = '', follow_type: str = None, + limit: int = 1000, **kwargs): """Get all accounts following `account`. (EOL)""" # `type` reserved word workaround if not follow_type and 'type' in kwargs: @@ -92,12 +92,12 @@ async def get_followers(context, account: str, start: str, follow_type: str = No valid_account(account), valid_account(start, allow_empty=True), valid_follow_type(follow_type), - valid_limit(limit, 1000, None)) + valid_limit(limit, 1000, 1000)) return [_legacy_follower(name, account, follow_type) for name in followers] @return_error_info -async def get_following(context, account: str, start: str, follow_type: str = None, - limit: int = None, **kwargs): +async def get_following(context, account: str, start: str = '', follow_type: str = None, + limit: int = 1000, **kwargs): """Get all accounts `account` follows. (EOL)""" # `type` reserved word workaround if not follow_type and 'type' in kwargs: @@ -109,7 +109,7 @@ async def get_following(context, account: str, start: str, follow_type: str = No valid_account(account), valid_account(start, allow_empty=True), valid_follow_type(follow_type), - valid_limit(limit, 1000, None)) + valid_limit(limit, 1000, 1000)) return [_legacy_follower(account, name, follow_type) for name in following] @return_error_info diff --git a/hive/server/hive_api/public.py b/hive/server/hive_api/public.py index e91126c0324f0a72549fe2646c89209869c00e54..8d2674530fdf10e0092d765a2b649d6d9f5849b5 100644 --- a/hive/server/hive_api/public.py +++ b/hive/server/hive_api/public.py @@ -43,7 +43,8 @@ async def list_followers(context, account:str, start:str='', limit:int=50, obser context['db'], valid_account(account), valid_account(start, allow_empty=True), - 'blog', valid_limit(limit, 100, 50)) + 1, # blog + valid_limit(limit, 100, 50)) return await accounts_by_name(context['db'], followers, observer, lite=True) async def list_following(context, account:str, start:str='', limit:int=50, observer:str=None): @@ -52,7 +53,8 @@ async def list_following(context, account:str, start:str='', limit:int=50, obser context['db'], valid_account(account), valid_account(start, allow_empty=True), - 'blog', valid_limit(limit, 100, 50)) + 1, # blog + valid_limit(limit, 100, 50)) return await accounts_by_name(context['db'], following, observer, lite=True) async def list_all_muted(context, account): diff --git a/tests/tests_api b/tests/tests_api index 143134910db644cb159e1f3e60f1d76e8eebc485..f9a494943bbd06daa7e51b53e2fd1b9207a4086c 160000 --- a/tests/tests_api +++ b/tests/tests_api @@ -1 +1 @@ -Subproject commit 143134910db644cb159e1f3e60f1d76e8eebc485 +Subproject commit f9a494943bbd06daa7e51b53e2fd1b9207a4086c