Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • hive/hivemind
1 result
Show changes
Commits on Source (78)
Showing
with 1082 additions and 468 deletions
......@@ -27,7 +27,7 @@ communities, providing a consensus interpretation layer for Hive applications.
- *communities:* mod roles/actions, members, feeds (in
1.5; [spec](https://gitlab.syncad.com/hive/hivemind/-/blob/master/docs/communities.md))
- *accounts:* normalized profile data, reputation
- *feeds:* un/follows and un/reblogs
- *feeds:* un/follows and un/reblogs: [spec](https://gitlab.syncad.com/hive/hivemind/-/blob/master/docs/follows.md)
### Hivemind does not track most blockchain operations
......
# Hive Follows Design
## Overview
All accounts are able to perform follow action on another account in order to:
- stay up to date with posts by the author you are interested in
- isolate posts by authors that the user is not interested in
- put user on blacklist and mark posts created by him
It is also possible to follow other account blacklists and mutes. So if user want to have the same mutes or/and blacklists as another user, there is such possibility.
#### Follow Actions
There are 16 follow actions:
1. **blog** - user follows another user
2. **follow** - the same as **blog**
3. **ignore** - user mutes another user, what results with hiding posts created by muted user, in some cases these posts can be grayed.
4. **blacklist** - marks user as blacklisted and his posts will be marked with 'my blacklist'
5. **follow_blacklist** - user follows another user's list of blacklisted users and will see 'blacklisted by <user>' if someone post is blacklisted by one of user who's blacklist is followed
6. **unblacklist** - removes user from own blacklist
7. **unfollow_blacklist** - stop following another user's list of blacklisted users.
8. **follow_muted** - user follows another user's list of muted users and posts created by these users will be hidden or grayed like be muted by user.
9. **unfollow_muted** - user stops follow another user's list of muted users.
10. **reset_blacklist** - Removes all users from user's list of blacklisted users.
11. **reset_following_list** - Removes all users from user's list of following users.
12. **reset_muted_list** - Removes all users from user's list of muted users.
13. **reset_follow_blacklist** - Removes all users from user's list of following another users blacklisted users.
14. **reset_follow_muted_list** - Removes all users from user's list of following another users muted users.
15. **reset_all_lists** - User will not follow, ignore or blacklist anyone, like new created user.
#### Follow Operation
To create follow operation, you need to user `custom_json_operation`. Field `id` have to be set to `follow`, in`required_posting_auths` you need to put `follower` name.
Field `json` have to be a list, first element must be a string value - `follow` and second has to be a json, which has to contains 3 keys:
- `follower` - user on which action will be performed.
- `following` - user on which another user will perform follow operation (when using one of resets action, this field is ignored, can be set to null or whatever). This field can be a string or a list. In case of list, specific follow action will be performed on every user from list.
- `what` - has to be a list and it has to contain one of follow actions. In case when we want to unfollow ir cancel ignore on specific user, list should be empty or we can action to empty string - `""` (be aware, removing user from blacklist needs `unblacklist` action)
Example follow operation:
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":\"cool-user\",\"what\":[\"follow\"]}]"
}
}
```
Example follow operation where user performs follow action on many users.
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":[\"cool-user\",\"cleverguy\"]\"what\":[\"follow\"]}]"
}
}
```
### Example Follow Operations
1. Follow user or users.
In this follow operation, user follows another user.
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":\"cool-user\",\"what\":[\"blog\"]}]"
}
}
```
If we want to set follow on multiple users in one operation, here is an example.
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":[\"cool-user\", \"clever-guy\", \"info-bot\"],\"what\":[\"follow\"]}]"
}
}
```
2. Ignore/mute user or users.
Example follow operation which mutes another user:
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":\"spamer\",\"what\":[\"ignore\"]}]"
}
}
```
3. Canceling follow or ignore from specific user.
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":\"someone\",\"what\":[]}]"
}
}
```
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":\"someone\",\"what\":[\"\"]}]"
}
}
```
4. Putting user on blacklist
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":\"suspected-guy\",\"what\":[\"blacklist\"]}]"
}
}
```
5. Removing user from blacklist
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":\"good-guy\",\"what\":[\"unblacklist\"]}]"
}
}
```
5. Following another user's list of blacklisted users
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":\"guy-who-knowns\",\"what\":[\"follow_blacklist\"]}]"
}
}
```
5. Stoping follow another user's list of blacklisted users
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":\"guywithfakeinfo\",\"what\":[\"unfollow_blacklist\"]}]"
}
}
```
6. Following another user's list of muted users
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":\"guyignorescommunity\",\"what\":[\"follow_muted\"]}]"
}
}
```
7. Stoping follow another user's list of muted users
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":\"guywithfakeinfo\",\"what\":[\"unfollow_muted\"]}]"
}
}
```
8. Reset user's list of blacklisted users
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":\"\",\"what\":[\"reset_blacklist\"]}]"
}
}
```
9. Reset user's list of following users
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":\"!@#$%^&*()_\",\"what\":[\"reset_following_list\"]}]"
}
}
```
10. Reset user's list of muted users
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":[\"!@#$%^&*()_\"],\"what\":[\"reset_muted_list\"]}]"
}
}
```
11. Reset user's list of following another users blacklisted users.
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":[\"!@#$%^&*()_\", \"fdsafsadf\"],\"what\":[\"reset_follow_blacklist\"]}]"
}
}
```
12. Reset user's list of following another users muted users.
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":[],\"what\":[\"reset_follow_muted_list\"]}]"
}
}
```
13. Clear user's all lists
```
{
"type": "custom_json_operation",
"value": {
"required_auths": [],
"required_posting_auths": [
"user-follower"
],
"id": "follow",
"json": "[\"follow\",{\"follower\":\"user-follower\",\"following\":null,\"what\":[\"reset_all_lists\"]}]"
}
}
```
......@@ -109,13 +109,6 @@ class DbState:
'hive_feed_cache_created_at_idx',
'hive_feed_cache_post_id_idx',
'hive_feed_cache_account_id_created_at_post_id_idx',
'hive_follows_following_state_id_idx', # (following, state, id)
'hive_follows_follower_state_idx', # (follower, state, created_at, following)
'hive_follows_follower_following_state_idx',
'hive_follows_block_num_idx',
'hive_follows_follower_where_blacklisted_idx',
'hive_follows_follower_where_follow_muted_idx',
'hive_follows_follower_where_follow_blacklists_idx',
'hive_posts_parent_id_id_idx',
'hive_posts_depth_idx',
'hive_posts_root_id_id_idx',
......@@ -140,6 +133,21 @@ class DbState:
'hive_votes_post_id_voter_id_idx',
'hive_notification_cache_block_num_idx',
'hive_notification_cache_dst_score_idx',
'follows_follower_idx',
'follows_following_idx',
'muted_follower_idx',
'muted_following_idx',
'blacklisted_follower_idx',
'blacklisted_following_idx',
'follow_muted_follower_idx',
'follow_muted_following_idx',
'follow_blacklisted_follower_idx',
'follow_blacklisted_following_idx',
'follows_block_num_idx',
'muted_block_num_idx',
'blacklisted_block_num_idx',
'follow_muted_block_num_idx',
'follow_blacklisted_block_num_idx',
]
to_return = {}
......@@ -447,6 +455,11 @@ class DbState:
cls._execute_query_with_modified_work_mem(db=db_mgr.db, sql=sql)
log.info("[MASSIVE] update_notification_cache executed in %.4fs", perf_counter() - time_start)
time_start = perf_counter()
sql = f"CALL {SCHEMA_NAME}.clear_muted_notifications();"
cls._execute_query_with_modified_work_mem(db=db_mgr.db, sql=sql)
log.info("[MASSIVE] clear_muted_notifications executed in %.4fs", perf_counter() - time_start)
@classmethod
def _finish_follow_count(cls, db, last_imported_block, current_imported_block):
with AutoDbDisposer(db, "finish_follow_count") as db_mgr:
......
......@@ -196,9 +196,9 @@ def build_metadata():
sa.Column('permlink_id', sa.Integer, nullable=False),
sa.Column('weight', sa.Numeric, nullable=False, server_default='0'),
sa.Column('rshares', sa.BigInteger, nullable=False, server_default='0'),
sa.Column('vote_percent', sa.Integer, server_default='0'),
sa.Column('vote_percent', sa.Integer, nullable=False, server_default='0'),
sa.Column('last_update', sa.DateTime, nullable=False, server_default='1970-01-01 00:00:00'),
sa.Column('num_changes', sa.Integer, server_default='0'),
sa.Column('num_changes', sa.Integer, nullable=False, server_default='0'),
sa.Column('block_num', sa.Integer, nullable=False),
sa.Column('is_effective', BOOLEAN, nullable=False, server_default='0'),
sa.UniqueConstraint(
......@@ -240,28 +240,6 @@ def build_metadata():
sa.UniqueConstraint('tag', name='hive_tag_data_ux1'),
)
sa.Table(
'hive_follows',
metadata,
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('follower', sa.Integer, nullable=False),
sa.Column('following', sa.Integer, nullable=False),
sa.Column('state', SMALLINT, nullable=False, server_default='1'),
sa.Column('created_at', sa.DateTime, nullable=False),
sa.Column('blacklisted', sa.Boolean, nullable=False, server_default='0'),
sa.Column('follow_blacklists', sa.Boolean, nullable=False, server_default='0'),
sa.Column('follow_muted', BOOLEAN, nullable=False, server_default='0'),
sa.Column('block_num', sa.Integer, nullable=False),
sa.UniqueConstraint('following', 'follower', name='hive_follows_ux1'), # core
sa.Index('hive_follows_following_state_id_idx', 'following', 'state', 'id'), # index used by condenser_get_followers
sa.Index('hive_follows_follower_state_idx', 'follower', 'state'),
sa.Index('hive_follows_follower_following_state_idx', 'follower', 'following', 'state'),
sa.Index('hive_follows_block_num_idx', 'block_num'),
sa.Index('hive_follows_follower_where_blacklisted_idx', 'follower', postgresql_where=sql_text('blacklisted')),
sa.Index('hive_follows_follower_where_follow_muted_idx', 'follower', postgresql_where=sql_text('follow_muted')),
sa.Index('hive_follows_follower_where_follow_blacklists_idx', 'follower', postgresql_where=sql_text('follow_blacklists')),
)
sa.Table(
'hive_reblogs',
metadata,
......@@ -317,6 +295,61 @@ def build_metadata():
metadata = build_metadata_community(metadata)
sa.Table(
'follows', metadata,
sa.Column('follower', sa.Integer, primary_key=True, nullable=False),
sa.Column('following', sa.Integer, primary_key=True, nullable=False),
sa.Column('block_num', sa.Integer, nullable=False),
sa.Index('follows_follower_idx', 'follower'),
sa.Index('follows_following_idx', 'following'),
sa.Index('follows_block_num_idx', 'block_num'),
schema=SCHEMA_NAME
)
sa.Table(
'muted', metadata,
sa.Column('follower', sa.Integer, primary_key=True, nullable=False),
sa.Column('following', sa.Integer, primary_key=True, nullable=False),
sa.Column('block_num', sa.Integer, nullable=False),
sa.Index('muted_follower_idx', 'follower'),
sa.Index('muted_following_idx', 'following'),
sa.Index('muted_block_num_idx', 'block_num'),
schema=SCHEMA_NAME
)
sa.Table(
'blacklisted', metadata,
sa.Column('follower', sa.Integer, primary_key=True, nullable=False),
sa.Column('following', sa.Integer, primary_key=True, nullable=False),
sa.Column('block_num', sa.Integer, nullable=False),
sa.Index('blacklisted_follower_idx', 'follower'),
sa.Index('blacklisted_following_idx', 'following'),
sa.Index('blacklisted_block_num_idx', 'block_num'),
schema=SCHEMA_NAME
)
sa.Table(
'follow_muted', metadata,
sa.Column('follower', sa.Integer, primary_key=True, nullable=False),
sa.Column('following', sa.Integer, primary_key=True, nullable=False),
sa.Column('block_num', sa.Integer, nullable=False),
sa.Index('follow_muted_follower_idx', 'follower'),
sa.Index('follow_muted_following_idx', 'following'),
sa.Index('follow_muted_block_num_idx', 'block_num'),
schema=SCHEMA_NAME
)
sa.Table(
'follow_blacklisted', metadata,
sa.Column('follower', sa.Integer, primary_key=True, nullable=False),
sa.Column('following', sa.Integer, primary_key=True, nullable=False),
sa.Column('block_num', sa.Integer, nullable=False),
sa.Index('follow_blacklisted_follower_idx', 'follower'),
sa.Index('follow_blacklisted_following_idx', 'following'),
sa.Index('follow_blacklisted_block_num_idx', 'block_num'),
schema=SCHEMA_NAME
)
return metadata
......@@ -551,6 +584,7 @@ def setup(db, admin_db):
def setup_runtime_code(db):
sql_scripts = [
"utility_functions.sql",
"follow_ops.sql",
"hive_accounts_view.sql",
"hive_accounts_info_view.sql",
"hive_posts_base_view.sql",
......@@ -567,13 +601,13 @@ def setup_runtime_code(db):
"delete_hive_posts_mentions.sql",
"notifications_view.sql",
"update_notification_cache.sql",
"clear_muted_notifications.sql",
"hot_and_trends.sql",
"update_hive_posts_children_count.sql",
"update_posts_rshares.sql",
"update_hive_post_root_id.sql",
"update_follow_count.sql",
"delete_reblog_feed_cache.sql",
"follows.sql",
"is_superuser.sql",
"update_hive_blocks_consistency_flag.sql",
"postgrest/home.sql",
......@@ -738,7 +772,6 @@ def reset_autovac(db):
'hive_accounts': (50000, 100000),
'hive_posts': (2500, 10000),
'hive_post_tags': (5000, 10000),
'hive_follows': (5000, 5000),
# 'hive_feed_cache': (5000, 5000),
# 'hive_reblogs': (5000, 5000),
}
......@@ -776,7 +809,7 @@ def set_logged_table_attribute(db, logged):
'hive_votes',
]
for table in logged_config:
for table in logged_config.items():
log.info(f"Setting {'LOGGED' if logged else 'UNLOGGED'} attribute on a table: {table}")
sql = """ALTER TABLE {} SET {}"""
db.query_no_return(sql.format(table, 'LOGGED' if logged else 'UNLOGGED'))
......
DROP FUNCTION IF EXISTS hivemind_app.clear_muted_notifications;
CREATE OR REPLACE PROCEDURE hivemind_app.clear_muted_notifications()
LANGUAGE sql
AS
$BODY$
DELETE FROM hivemind_app.hive_notification_cache AS n
WHERE EXISTS (
SELECT NULL FROM hivemind_app.muted AS m
WHERE n.src=m.following AND n.dst=m.follower
);
$BODY$;
DROP TYPE IF EXISTS hivemind_app.follow CASCADE;
CREATE TYPE hivemind_app.follow AS (
follower TEXT,
following TEXT,
block_num INT
);
DROP TYPE IF EXISTS hivemind_app.follow_ids CASCADE;
CREATE TYPE hivemind_app.follow_ids AS (
follower_id INTEGER,
following_id INTEGER,
block_num INTEGER
);
DROP TYPE IF EXISTS hivemind_app.follow_updates CASCADE;
CREATE TYPE hivemind_app.follow_updates AS (
id INTEGER,
mode TEXT,
changes hivemind_app.follow[]
);
DROP TYPE IF EXISTS hivemind_app.mute CASCADE;
CREATE TYPE hivemind_app.mute AS (
follower TEXT,
following TEXT,
block_num INT
);
DROP TYPE IF EXISTS hivemind_app.mute_ids CASCADE;
CREATE TYPE hivemind_app.mute_ids AS (
follower_id INTEGER,
following_id INTEGER,
block_num INTEGER
);
DROP TYPE IF EXISTS hivemind_app.mute_updates CASCADE;
CREATE TYPE hivemind_app.mute_updates AS (
id INTEGER,
mode TEXT,
changes hivemind_app.mute[]
);
DROP TYPE IF EXISTS hivemind_app.blacklist CASCADE;
CREATE TYPE hivemind_app.blacklist AS (
follower TEXT,
following TEXT,
block_num INT
);
DROP TYPE IF EXISTS hivemind_app.blacklist_ids CASCADE;
CREATE TYPE hivemind_app.blacklist_ids AS (
follower_id INTEGER,
following_id INTEGER,
block_num INTEGER
);
DROP TYPE IF EXISTS hivemind_app.blacklist_updates CASCADE;
CREATE TYPE hivemind_app.blacklist_updates AS (
id INTEGER,
mode TEXT,
changes hivemind_app.blacklist[]
);
DROP TYPE IF EXISTS hivemind_app.follow_mute CASCADE;
CREATE TYPE hivemind_app.follow_mute AS (
follower TEXT,
following TEXT,
block_num INT
);
DROP TYPE IF EXISTS hivemind_app.follow_mute_ids CASCADE;
CREATE TYPE hivemind_app.follow_mute_ids AS (
follower_id INTEGER,
following_id INTEGER,
block_num INTEGER
);
DROP TYPE IF EXISTS hivemind_app.follow_mute_updates CASCADE;
CREATE TYPE hivemind_app.follow_mute_updates AS (
id INTEGER,
mode TEXT,
changes hivemind_app.follow_mute[]
);
DROP TYPE IF EXISTS hivemind_app.follow_blacklist CASCADE;
CREATE TYPE hivemind_app.follow_blacklist AS (
follower TEXT,
following TEXT,
block_num INT
);
DROP TYPE IF EXISTS hivemind_app.follow_blacklist_ids CASCADE;
CREATE TYPE hivemind_app.follow_blacklist_ids AS (
follower_id INTEGER,
following_id INTEGER,
block_num INTEGER
);
DROP TYPE IF EXISTS hivemind_app.follow_blacklist_updates CASCADE;
CREATE TYPE hivemind_app.follow_blacklist_updates AS (
id INTEGER,
mode TEXT,
changes hivemind_app.follow_blacklist[]
);
DROP FUNCTION IF EXISTS hivemind_app.insert_follows;
CREATE OR REPLACE FUNCTION hivemind_app.insert_follows(_changes hivemind_app.follow_ids[])
RETURNS INTEGER AS $$
INSERT INTO hivemind_app.follows (follower, following, block_num)
SELECT v.follower_id, v.following_id, v.block_num
FROM UNNEST(_changes) AS v(follower_id, following_id, block_num)
ORDER BY v.block_num
ON CONFLICT (follower, following) DO UPDATE
SET block_num = EXCLUDED.block_num
RETURNING 1;
$$ LANGUAGE sql;
DROP FUNCTION IF EXISTS hivemind_app.delete_follows;
CREATE OR REPLACE FUNCTION hivemind_app.delete_follows(_changes hivemind_app.follow_ids[])
RETURNS INTEGER AS $$
DELETE FROM hivemind_app.follows f
USING UNNEST(_changes) AS v(follower_id, following_id)
WHERE f.follower = v.follower_id
AND f.following = v.following_id
RETURNING 1;
$$ LANGUAGE sql;
DROP FUNCTION IF EXISTS hivemind_app.reset_follows;
CREATE OR REPLACE FUNCTION hivemind_app.reset_follows(_changes hivemind_app.follow_ids[])
RETURNS INTEGER AS $$
DELETE FROM hivemind_app.follows f
USING UNNEST(_changes) AS v(follower_id, following_id, block_num)
WHERE f.follower = v.follower_id
RETURNING 1;
$$ LANGUAGE sql;
DROP FUNCTION IF EXISTS hivemind_app.insert_muted;
CREATE OR REPLACE FUNCTION hivemind_app.insert_muted(_changes hivemind_app.mute_ids[])
RETURNS INTEGER AS $$
INSERT INTO hivemind_app.muted (follower, following, block_num)
SELECT v.follower_id, v.following_id, v.block_num
FROM UNNEST(_changes) AS v(follower_id, following_id, block_num)
ORDER BY v.block_num
ON CONFLICT (follower, following) DO UPDATE
SET block_num = EXCLUDED.block_num
RETURNING 1;
$$ LANGUAGE sql;
DROP FUNCTION IF EXISTS hivemind_app.delete_muted;
CREATE OR REPLACE FUNCTION hivemind_app.delete_muted(_changes hivemind_app.mute_ids[])
RETURNS INTEGER AS $$
DELETE FROM hivemind_app.muted f
USING UNNEST(_changes) AS v(follower_id, following_id)
WHERE f.follower = v.follower_id
AND f.following = v.following_id
RETURNING 1;
$$ LANGUAGE sql;
DROP FUNCTION IF EXISTS hivemind_app.reset_muted;
CREATE OR REPLACE FUNCTION hivemind_app.reset_muted(_changes hivemind_app.mute_ids[])
RETURNS INTEGER AS $$
DELETE FROM hivemind_app.muted f
USING UNNEST(_changes) AS v(follower_id, following_id, block_num)
WHERE f.follower = v.follower_id
RETURNING 1;
$$ LANGUAGE sql;
DROP FUNCTION IF EXISTS hivemind_app.insert_blacklisted;
CREATE OR REPLACE FUNCTION hivemind_app.insert_blacklisted(_changes hivemind_app.blacklist_ids[])
RETURNS INTEGER AS $$
INSERT INTO hivemind_app.blacklisted (follower, following, block_num)
SELECT v.follower_id, v.following_id, v.block_num
FROM UNNEST(_changes) AS v(follower_id, following_id, block_num)
ORDER BY v.block_num
ON CONFLICT (follower, following) DO UPDATE
SET block_num = EXCLUDED.block_num
RETURNING 1;
$$ LANGUAGE sql;
DROP FUNCTION IF EXISTS hivemind_app.delete_blacklisted;
CREATE OR REPLACE FUNCTION hivemind_app.delete_blacklisted(_changes hivemind_app.blacklist_ids[])
RETURNS INTEGER AS $$
DELETE FROM hivemind_app.blacklisted f
USING UNNEST(_changes) AS v(follower_id, following_id)
WHERE f.follower = v.follower_id
AND f.following = v.following_id
RETURNING 1;
$$ LANGUAGE sql;
DROP FUNCTION IF EXISTS hivemind_app.reset_blacklisted;
CREATE OR REPLACE FUNCTION hivemind_app.reset_blacklisted(_changes hivemind_app.blacklist_ids[])
RETURNS INTEGER AS $$
DELETE FROM hivemind_app.blacklisted f
USING UNNEST(_changes) AS v(follower_id, following_id, block_num)
WHERE f.follower = v.follower_id
RETURNING 1;
$$ LANGUAGE sql;
DROP FUNCTION IF EXISTS hivemind_app.insert_follow_muted;
CREATE OR REPLACE FUNCTION hivemind_app.insert_follow_muted(_changes hivemind_app.follow_mute_ids[])
RETURNS INTEGER AS $$
INSERT INTO hivemind_app.follow_muted (follower, following, block_num)
SELECT v.follower_id, v.following_id, v.block_num
FROM UNNEST(_changes) AS v(follower_id, following_id, block_num)
ORDER BY v.block_num
ON CONFLICT (follower, following) DO UPDATE
SET block_num = EXCLUDED.block_num
RETURNING 1;
$$ LANGUAGE sql;
DROP FUNCTION IF EXISTS hivemind_app.delete_follow_muted;
CREATE OR REPLACE FUNCTION hivemind_app.delete_follow_muted(_changes hivemind_app.follow_mute_ids[])
RETURNS INTEGER AS $$
DELETE FROM hivemind_app.follow_muted f
USING UNNEST(_changes) AS v(follower_id, following_id)
WHERE f.follower = v.follower_id
AND f.following = v.following_id
RETURNING 1;
$$ LANGUAGE sql;
DROP FUNCTION IF EXISTS hivemind_app.reset_follow_muted;
CREATE OR REPLACE FUNCTION hivemind_app.reset_follow_muted(_changes hivemind_app.follow_mute_ids[])
RETURNS INTEGER AS $$
DELETE FROM hivemind_app.follow_muted f
USING UNNEST(_changes) AS v(follower_id, following_id, block_num)
WHERE f.follower = v.follower_id
RETURNING 1;
$$ LANGUAGE sql;
DROP FUNCTION IF EXISTS hivemind_app.insert_follow_blacklisted;
CREATE OR REPLACE FUNCTION hivemind_app.insert_follow_blacklisted(_changes hivemind_app.follow_blacklist_ids[])
RETURNS INTEGER AS $$
INSERT INTO hivemind_app.follow_blacklisted (follower, following, block_num)
SELECT v.follower_id, v.following_id, v.block_num
FROM UNNEST(_changes) AS v(follower_id, following_id, block_num)
ORDER BY v.block_num
ON CONFLICT (follower, following) DO UPDATE
SET block_num = EXCLUDED.block_num
RETURNING 1;
$$ LANGUAGE sql;
DROP FUNCTION IF EXISTS hivemind_app.delete_follow_blacklisted;
CREATE OR REPLACE FUNCTION hivemind_app.delete_follow_blacklisted(_changes hivemind_app.follow_blacklist_ids[])
RETURNS INTEGER AS $$
DELETE FROM hivemind_app.follow_blacklisted f
USING UNNEST(_changes) AS v(follower_id, following_id)
WHERE f.follower = v.follower_id
AND f.following = v.following_id
RETURNING 1;
$$ LANGUAGE sql;
DROP FUNCTION IF EXISTS hivemind_app.reset_follow_blacklisted;
CREATE OR REPLACE FUNCTION hivemind_app.reset_follow_blacklisted(_changes hivemind_app.follow_blacklist_ids[])
RETURNS INTEGER AS $$
DELETE FROM hivemind_app.follow_blacklisted f
USING UNNEST(_changes) AS v(follower_id, following_id, block_num)
WHERE f.follower = v.follower_id
RETURNING 1;
$$ LANGUAGE sql;
DROP PROCEDURE IF EXISTS hivemind_app.flush_follows CASCADE;
CREATE OR REPLACE PROCEDURE hivemind_app.flush_follows(_follow_updates hivemind_app.follow_updates[], _muted_updates hivemind_app.mute_updates[], _blacklisted_updates hivemind_app.blacklist_updates[], _follow_muted_updates hivemind_app.follow_mute_updates[], _follow_blacklisted_updates hivemind_app.follow_blacklist_updates[], _impacted_accounts TEXT[])
LANGUAGE sql
AS $BODY$
WITH accounts_id AS MATERIALIZED (
SELECT ha.name, ha.id
FROM hivemind_app.hive_accounts ha
JOIN ( SELECT UNNEST( _impacted_accounts ) AS name ) AS im ON im.name = ha.name
),
change_follows AS MATERIALIZED (
SELECT
CASE upd_with_ids.mode
WHEN 'insert' THEN (
hivemind_app.insert_follows(upd_with_ids.changes)
)
WHEN 'delete' THEN (
hivemind_app.delete_follows(upd_with_ids.changes)
)
WHEN 'reset' THEN (
hivemind_app.reset_follows(upd_with_ids.changes)
)
END
FROM (
SELECT
upd.id,
upd.mode,
ARRAY_AGG( ROW(r.id, g.id, ch.block_num)::hivemind_app.follow_ids) AS changes
FROM UNNEST(_follow_updates) AS upd
CROSS JOIN LATERAL UNNEST(upd.changes) AS ch(follower, following, block_num)
JOIN accounts_id AS r ON ch.follower = r.name
LEFT JOIN accounts_id AS g ON ch.following = g.name
GROUP BY upd.id, upd.mode
ORDER BY upd.id
) AS upd_with_ids
ORDER BY upd_with_ids.id
),
change_muted AS MATERIALIZED (
SELECT
CASE upd_with_ids.mode
WHEN 'insert' THEN (
hivemind_app.insert_muted(upd_with_ids.changes)
)
WHEN 'delete' THEN (
hivemind_app.delete_muted(upd_with_ids.changes)
)
WHEN 'reset' THEN (
hivemind_app.reset_muted(upd_with_ids.changes)
)
END
FROM (
SELECT
upd.id,
upd.mode,
ARRAY_AGG( ROW(r.id, g.id, ch.block_num)::hivemind_app.mute_ids) AS changes
FROM UNNEST(_muted_updates) AS upd
CROSS JOIN LATERAL UNNEST(upd.changes) AS ch(follower, following, block_num)
JOIN accounts_id AS r ON ch.follower = r.name
LEFT JOIN accounts_id AS g ON ch.following = g.name
GROUP BY upd.id, upd.mode
ORDER BY upd.id
) AS upd_with_ids
ORDER BY upd_with_ids.id
),
change_blacklisted AS MATERIALIZED (
SELECT
CASE upd_with_ids.mode
WHEN 'insert' THEN (
hivemind_app.insert_blacklisted(upd_with_ids.changes)
)
WHEN 'delete' THEN (
hivemind_app.delete_blacklisted(upd_with_ids.changes)
)
WHEN 'reset' THEN (
hivemind_app.reset_blacklisted(upd_with_ids.changes)
)
END
FROM (
SELECT
upd.id,
upd.mode,
ARRAY_AGG( ROW(r.id, g.id, ch.block_num)::hivemind_app.blacklist_ids) AS changes
FROM UNNEST(_blacklisted_updates) AS upd
CROSS JOIN LATERAL UNNEST(upd.changes) AS ch(follower, following, block_num)
JOIN accounts_id AS r ON ch.follower = r.name
LEFT JOIN accounts_id AS g ON ch.following = g.name
GROUP BY upd.id, upd.mode
ORDER BY upd.id
) AS upd_with_ids
ORDER BY upd_with_ids.id
),
change_follow_muted AS MATERIALIZED (
SELECT
CASE upd_with_ids.mode
WHEN 'insert' THEN (
hivemind_app.insert_follow_muted(upd_with_ids.changes)
)
WHEN 'delete' THEN (
hivemind_app.delete_follow_muted(upd_with_ids.changes)
)
WHEN 'reset' THEN (
hivemind_app.reset_follow_muted(upd_with_ids.changes)
)
END
FROM (
SELECT
upd.id,
upd.mode,
ARRAY_AGG( ROW(r.id, g.id, ch.block_num)::hivemind_app.follow_mute_ids) AS changes
FROM UNNEST(_follow_muted_updates) AS upd
CROSS JOIN LATERAL UNNEST(upd.changes) AS ch(follower, following, block_num)
JOIN accounts_id AS r ON ch.follower = r.name
LEFT JOIN accounts_id AS g ON ch.following = g.name
GROUP BY upd.id, upd.mode
ORDER BY upd.id
) AS upd_with_ids
ORDER BY upd_with_ids.id
),
change_follow_blacklisted AS MATERIALIZED (
SELECT
CASE upd_with_ids.mode
WHEN 'insert' THEN (
hivemind_app.insert_follow_blacklisted(upd_with_ids.changes)
)
WHEN 'delete' THEN (
hivemind_app.delete_follow_blacklisted(upd_with_ids.changes)
)
WHEN 'reset' THEN (
hivemind_app.reset_follow_blacklisted(upd_with_ids.changes)
)
END
FROM (
SELECT
upd.id,
upd.mode,
ARRAY_AGG( ROW(r.id, g.id, ch.block_num)::hivemind_app.follow_blacklist_ids) AS changes
FROM UNNEST(_follow_blacklisted_updates) AS upd
CROSS JOIN LATERAL UNNEST(upd.changes) AS ch(follower, following, block_num)
JOIN accounts_id AS r ON ch.follower = r.name
LEFT JOIN accounts_id AS g ON ch.following = g.name
GROUP BY upd.id, upd.mode
ORDER BY upd.id
) AS upd_with_ids
ORDER BY upd_with_ids.id
)
SELECT COUNT(*)
FROM (
SELECT * FROM change_follows
UNION ALL
SELECT * FROM change_muted
UNION ALL
SELECT * FROM change_blacklisted
UNION ALL
SELECT * FROM change_follow_muted
UNION ALL
SELECT * FROM change_follow_blacklisted
) AS x(val)
GROUP BY val;
$BODY$;
DROP FUNCTION IF EXISTS hivemind_app.follow_reset_blacklist(character varying, integer)
;
CREATE OR REPLACE FUNCTION hivemind_app.follow_reset_blacklist(in _follower hivemind_app.hive_accounts.name%TYPE, in _block_num hivemind_app.hive_follows.block_num%TYPE)
RETURNS VOID
LANGUAGE plpgsql
AS
$function$
DECLARE
__account_id INT;
BEGIN
__account_id = hivemind_app.find_account_id( _follower, False );
UPDATE hivemind_app.hive_follows hf -- follow_reset_blacklist
SET blacklisted = false, block_num = _block_num
WHERE hf.follower = __account_id AND hf.blacklisted;
END
$function$
;
DROP FUNCTION IF EXISTS hivemind_app.follow_reset_following_list(character varying, integer)
;
CREATE OR REPLACE FUNCTION hivemind_app.follow_reset_following_list(in _follower hivemind_app.hive_accounts.name%TYPE, in _block_num hivemind_app.hive_follows.block_num%TYPE)
RETURNS VOID
LANGUAGE plpgsql
AS
$function$
DECLARE
__account_id INT;
BEGIN
__account_id = hivemind_app.find_account_id( _follower, False );
UPDATE hivemind_app.hive_follows hf -- follow_reset_following_list
SET state = 0, block_num = _block_num
WHERE hf.follower = __account_id AND hf.state = 1;
END
$function$
;
DROP FUNCTION IF EXISTS hivemind_app.follow_reset_muted_list(character varying, integer)
;
CREATE OR REPLACE FUNCTION hivemind_app.follow_reset_muted_list(in _follower hivemind_app.hive_accounts.name%TYPE, in _block_num hivemind_app.hive_follows.block_num%TYPE)
RETURNS VOID
LANGUAGE plpgsql
AS
$function$
DECLARE
__account_id INT;
BEGIN
__account_id = hivemind_app.find_account_id( _follower, False );
UPDATE hivemind_app.hive_follows hf -- follow_reset_muted_list
SET state = 0, block_num = _block_num
WHERE hf.follower = __account_id AND hf.state = 2;
END
$function$
;
DROP FUNCTION IF EXISTS hivemind_app.follow_reset_follow_blacklist(character varying, integer)
;
CREATE OR REPLACE FUNCTION hivemind_app.follow_reset_follow_blacklist(in _follower hivemind_app.hive_accounts.name%TYPE, in _block_num hivemind_app.hive_follows.block_num%TYPE)
RETURNS VOID
LANGUAGE plpgsql
AS
$function$
DECLARE
__account_id INT;
BEGIN
__account_id = hivemind_app.find_account_id( _follower, False );
UPDATE hivemind_app.hive_follows hf -- follow_reset_follow_blacklist
SET follow_blacklists = false, block_num = _block_num
WHERE hf.follower = __account_id AND hf.follow_blacklists;
END
$function$
;
DROP FUNCTION IF EXISTS hivemind_app.follow_reset_follow_muted_list(character varying, integer)
;
CREATE OR REPLACE FUNCTION hivemind_app.follow_reset_follow_muted_list(in _follower hivemind_app.hive_accounts.name%TYPE, in _block_num hivemind_app.hive_follows.block_num%TYPE)
RETURNS VOID
LANGUAGE plpgsql
AS
$function$
DECLARE
__account_id INT;
BEGIN
__account_id = hivemind_app.find_account_id( _follower, False );
UPDATE hivemind_app.hive_follows hf -- follow_reset_follow_muted_list
SET follow_muted = false, block_num = _block_num
WHERE hf.follower = __account_id AND hf.follow_muted;
END
$function$
;
DROP FUNCTION IF EXISTS hivemind_app.follow_reset_all_lists(character varying, integer)
;
CREATE OR REPLACE FUNCTION hivemind_app.follow_reset_all_lists(in _follower hivemind_app.hive_accounts.name%TYPE, in _block_num hivemind_app.hive_follows.block_num%TYPE)
RETURNS VOID
LANGUAGE plpgsql
AS
$function$
DECLARE
__account_id INT;
BEGIN
__account_id = hivemind_app.find_account_id( _follower, False );
UPDATE hivemind_app.hive_follows hf -- follow_reset_all_lists
SET blacklisted = false, follow_blacklists = false, follow_muted = false, state = 0, block_num = _block_num
WHERE hf.follower = __account_id;
END
$function$
;
......@@ -260,25 +260,24 @@ BEGIN
RETURN QUERY
WITH blacklisters AS MATERIALIZED --all blacklists followed by account
(
SELECT following as id FROM hivemind_app.hive_follows WHERE follow_blacklists AND follower = _observer_id -- hive_follows_follower_where_follow_blacklists_idx
SELECT following AS id FROM hivemind_app.follow_blacklisted WHERE follower = _observer_id -- follows_follower_idx
),
indirects AS MATERIALIZED -- get all indirectly blacklisted accounts with the ids of their sources
(
SELECT blacklister_follows.following AS blacklisted_id,
blacklister_follows.follower AS blacklister_id
FROM blacklisters
JOIN hivemind_app.hive_follows blacklister_follows ON blacklister_follows.follower = blacklisters.id -- need this to get all accounts blacklisted by blacklister
WHERE blacklister_follows.blacklisted --hive_follows_follower_where_blacklisted_idx
JOIN hivemind_app.blacklisted AS blacklister_follows ON blacklister_follows.follower = blacklisters.id -- need this to get all accounts blacklisted by blacklister
)
SELECT following AS blacklisted_id, -- directly blacklisted accounts
'my blacklist'::text AS source
FROM hivemind_app.hive_follows
WHERE hive_follows.blacklisted AND hive_follows.follower = _observer_id --hive_follows_follower_where_blacklisted_idx
FROM hivemind_app.blacklisted
WHERE blacklisted.follower = _observer_id -- blacklisted_follower_idx
UNION ALL
SELECT indirects.blacklisted_id AS blacklisted_id, -- collapse duplicate indirectly blacklisted accounts and aggreagate their sources
string_agg('blacklisted by '::text || blacklister_accounts.name::text, ','::text ORDER BY blacklister_accounts.name) AS source
FROM indirects
JOIN hivemind_app.hive_accounts blacklister_accounts ON blacklister_accounts.id = indirects.blacklister_id -- need this to get name of blacklister, use hive_accounts_ux1
JOIN hivemind_app.hive_accounts AS blacklister_accounts ON blacklister_accounts.id = indirects.blacklister_id -- need this to get name of blacklister, use hive_accounts_ux1
GROUP BY indirects.blacklisted_id;
END IF;
END;
......
......@@ -9,7 +9,6 @@ $BODY$
$BODY$
;
DROP FUNCTION IF EXISTS hivemind_app.block_before_head CASCADE;
CREATE OR REPLACE FUNCTION hivemind_app.block_before_head( in _time INTERVAL )
RETURNS hivemind_app.blocks_view.num%TYPE
......@@ -17,4 +16,13 @@ LANGUAGE 'sql' STABLE
AS
$BODY$
SELECT hive.app_get_current_block_num( 'hivemind_app' ) - CAST( extract(epoch from _time)/3 as INTEGER );
$BODY$;
DROP FUNCTION IF EXISTS hivemind_app.block_before_irreversible CASCADE;
CREATE OR REPLACE FUNCTION hivemind_app.block_before_irreversible( in _time INTERVAL )
RETURNS hivemind_app.blocks_view.num%TYPE
LANGUAGE 'sql' STABLE
AS
$BODY$
SELECT hive.app_get_irreversible_block( 'hivemind_app' ) - CAST( extract(epoch from _time)/3 as INTEGER );
$BODY$;
DROP VIEW IF EXISTS hivemind_app.muted_accounts_by_id_view CASCADE;
CREATE OR REPLACE VIEW hivemind_app.muted_accounts_by_id_view AS
SELECT hive_follows.follower AS observer_id,
hive_follows.following AS muted_id
FROM hivemind_app.hive_follows
WHERE hive_follows.state = 2
SELECT
follower AS observer_id,
following AS muted_id
FROM hivemind_app.muted
UNION
SELECT hive_follows_direct.follower AS observer_id,
hive_follows_indirect.following AS muted_id
FROM hivemind_app.hive_follows hive_follows_direct
JOIN hivemind_app.hive_follows hive_follows_indirect ON hive_follows_direct.following = hive_follows_indirect.follower
WHERE hive_follows_direct.follow_muted AND hive_follows_indirect.state = 2;
SELECT
muted_direct.follower AS observer_id,
muted_indirect.following AS muted_id
FROM hivemind_app.follow_muted AS muted_direct
JOIN hivemind_app.muted AS muted_indirect ON muted_direct.following = muted_indirect.follower;
......@@ -26,13 +26,13 @@ END
$function$;
DROP FUNCTION IF EXISTS hivemind_app.encode_bitwise_mask;
CREATE OR REPLACE FUNCTION hivemind_app.encode_bitwise_mask(muted_reasons INT[])
CREATE OR REPLACE FUNCTION hivemind_app.encode_bitwise_mask(post_muted_reasons INT[])
RETURNS INT AS $$
DECLARE
mask INT := 0;
number INT;
BEGIN
FOREACH number IN ARRAY muted_reasons
FOREACH number IN ARRAY post_muted_reasons
LOOP
mask := mask | (1 << number);
END LOOP;
......@@ -42,13 +42,13 @@ $$ LANGUAGE plpgsql;
DROP TYPE IF EXISTS hivemind_app.process_community_post_result CASCADE;
CREATE TYPE hivemind_app.process_community_post_result AS (
is_muted bool,
is_post_muted bool,
community_id integer, -- hivemind_app.hive_posts.community_id%TYPE
muted_reasons INTEGER
post_muted_reasons INTEGER
);
DROP FUNCTION IF EXISTS hivemind_app.process_community_post;
CREATE OR REPLACE FUNCTION hivemind_app.process_community_post(_block_num hivemind_app.hive_posts.block_num%TYPE, _community_support_start_block hivemind_app.hive_posts.block_num%TYPE, _parent_permlink hivemind_app.hive_permlink_data.permlink%TYPE, _author_id hivemind_app.hive_posts.author_id%TYPE, _is_comment bool, _is_parent_muted bool, _community_id hivemind_app.hive_posts.community_id%TYPE)
CREATE OR REPLACE FUNCTION hivemind_app.process_community_post(_block_num hivemind_app.hive_posts.block_num%TYPE, _community_support_start_block hivemind_app.hive_posts.block_num%TYPE, _parent_permlink hivemind_app.hive_permlink_data.permlink%TYPE, _author_id hivemind_app.hive_posts.author_id%TYPE, _is_comment bool, _is_parent_post_muted bool, _community_id hivemind_app.hive_posts.community_id%TYPE)
RETURNS hivemind_app.process_community_post_result
LANGUAGE plpgsql
as
......@@ -60,12 +60,12 @@ declare
__community_type_topic CONSTANT SMALLINT := 1;
__community_type_journal CONSTANT SMALLINT := 2;
__community_type_council CONSTANT SMALLINT := 3;
__is_muted BOOL := TRUE;
__is_post_muted BOOL := TRUE;
__community_id hivemind_app.hive_posts.community_id%TYPE;
__muted_reasons INTEGER[] := ARRAY[]::INTEGER[];
__post_muted_reasons INTEGER[] := ARRAY[]::INTEGER[];
BEGIN
IF _block_num < _community_support_start_block THEN
__is_muted := FALSE;
__is_post_muted := FALSE;
__community_id := NULL;
ELSE
IF _is_comment = TRUE THEN
......@@ -76,36 +76,36 @@ BEGIN
IF __community_id IS NOT NULL THEN
IF __community_type_id = __community_type_topic THEN
__is_muted := FALSE;
__is_post_muted := FALSE;
ELSE
IF __community_type_id = __community_type_journal AND _is_comment = TRUE THEN
__is_muted := FALSE;
__is_post_muted := FALSE;
ELSE
select role_id into __role_id from hivemind_app.hive_roles where hivemind_app.hive_roles.community_id = __community_id AND account_id = _author_id;
IF __community_type_id = __community_type_journal AND _is_comment = FALSE AND __role_id IS NOT NULL AND __role_id >= __member_role THEN
__is_muted := FALSE;
__is_post_muted := FALSE;
ELSIF __community_type_id = __community_type_council AND __role_id IS NOT NULL AND __role_id >= __member_role THEN
__is_muted := FALSE;
__is_post_muted := FALSE;
ELSE
-- This means the post was muted because of community reasons, 1 is MUTED_COMMUNITY_TYPE see community.py for the ENUM definition
__muted_reasons := ARRAY[1];
__post_muted_reasons := ARRAY[1];
END IF;
END IF;
END IF;
ELSE
__is_muted := FALSE;
__is_post_muted := FALSE;
END IF;
-- __is_muted can be TRUE here if it's a comment and its parent is muted
IF _is_parent_muted = TRUE THEN
__is_muted := TRUE;
-- __is_post_muted can be TRUE here if it's a comment and its parent is muted
IF _is_parent_post_muted = TRUE THEN
__is_post_muted := TRUE;
-- 2 is MUTED_PARENT, see community.py for the ENUM definition
__muted_reasons := array_append(__muted_reasons, 2);
__post_muted_reasons := array_append(__post_muted_reasons, 2);
END IF;
END IF;
RETURN (__is_muted, __community_id, hivemind_app.encode_bitwise_mask(__muted_reasons))::hivemind_app.process_community_post_result;
RETURN (__is_post_muted, __community_id, hivemind_app.encode_bitwise_mask(__post_muted_reasons))::hivemind_app.process_community_post_result;
END;
$$ STABLE;
......@@ -121,8 +121,8 @@ CREATE OR REPLACE FUNCTION hivemind_app.process_hive_post_operation(
in _block_num hivemind_app.hive_posts.block_num%TYPE,
in _metadata_tags VARCHAR[])
RETURNS TABLE (is_new_post boolean, id hivemind_app.hive_posts.id%TYPE, author_id hivemind_app.hive_posts.author_id%TYPE, permlink_id hivemind_app.hive_posts.permlink_id%TYPE,
post_category hivemind_app.hive_category_data.category%TYPE, parent_id hivemind_app.hive_posts.parent_id%TYPE, community_id hivemind_app.hive_posts.community_id%TYPE,
is_valid hivemind_app.hive_posts.is_valid%TYPE, is_muted hivemind_app.hive_posts.is_muted%TYPE, depth hivemind_app.hive_posts.depth%TYPE)
post_category hivemind_app.hive_category_data.category%TYPE, parent_id hivemind_app.hive_posts.parent_id%TYPE, parent_author_id hivemind_app.hive_posts.author_id%TYPE, community_id hivemind_app.hive_posts.community_id%TYPE,
is_valid hivemind_app.hive_posts.is_valid%TYPE, is_post_muted hivemind_app.hive_posts.is_muted%TYPE, depth hivemind_app.hive_posts.depth%TYPE, is_author_muted BOOLEAN)
LANGUAGE plpgsql
AS
$function$
......@@ -137,64 +137,94 @@ BEGIN
ON CONFLICT DO NOTHING
;
IF _parent_author != '' THEN
RETURN QUERY INSERT INTO hivemind_app.hive_posts as hp
RETURN QUERY
WITH selected_posts AS (
SELECT
s.parent_id,
s.parent_author_id,
s.depth,
(s.composite).community_id,
s.category_id,
s.root_id,
(s.composite).is_post_muted,
s.is_valid,
s.author_id,
s.permlink_id,
s.created_at,
s.updated_at,
s.sc_hot,
s.sc_trend,
s.active,
s.payout_at,
s.cashout_time,
s.counter_deleted,
s.block_num,
s.block_num_created,
(s.composite).post_muted_reasons
FROM (
SELECT
hivemind_app.process_community_post(_block_num, _community_support_start_block, _parent_permlink, ha.id, TRUE, php.is_muted, php.community_id) as composite,
php.id AS parent_id,
php.author_id AS parent_author_id,
php.depth + 1 AS depth,
COALESCE(php.category_id, (select hcg.id from hivemind_app.hive_category_data hcg where hcg.category = _parent_permlink)) AS category_id,
(CASE(php.root_id)
WHEN 0 THEN php.id
ELSE php.root_id
END) AS root_id,
php.is_valid AS is_valid,
ha.id AS author_id, hpd.id AS permlink_id, _date AS created_at,
_date AS updated_at,
hivemind_app.calculate_time_part_of_hot(_date) AS sc_hot,
hivemind_app.calculate_time_part_of_trending(_date) AS sc_trend,
_date AS active, (_date + INTERVAL '7 days') AS payout_at, (_date + INTERVAL '7 days') AS cashout_time,
0 AS counter_deleted,
_block_num as block_num, _block_num as block_num_created
FROM hivemind_app.hive_accounts ha,
hivemind_app.hive_permlink_data hpd,
hivemind_app.hive_posts php
INNER JOIN hivemind_app.hive_accounts pha ON pha.id = php.author_id
INNER JOIN hivemind_app.hive_permlink_data phpd ON phpd.id = php.permlink_id
WHERE pha.name = _parent_author AND phpd.permlink = _parent_permlink AND
ha.name = _author AND hpd.permlink = _permlink AND php.counter_deleted = 0
) AS s
)
INSERT INTO hivemind_app.hive_posts as hp
(parent_id, depth, community_id, category_id,
root_id, is_muted, is_valid,
author_id, permlink_id, created_at, updated_at, sc_hot, sc_trend, active, payout_at, cashout_time, counter_deleted, block_num, block_num_created, muted_reasons)
SELECT
s.parent_id,
s.depth,
(s.composite).community_id,
s.category_id,
s.root_id,
(s.composite).is_muted,
s.is_valid,
s.author_id,
s.permlink_id,
s.created_at,
s.updated_at,
s.sc_hot,
s.sc_trend,
s.active,
s.payout_at,
s.cashout_time,
s.counter_deleted,
s.block_num,
s.block_num_created,
(s.composite).muted_reasons
FROM (
SELECT
hivemind_app.process_community_post(_block_num, _community_support_start_block, _parent_permlink, ha.id, TRUE, php.is_muted, php.community_id) as composite,
php.id AS parent_id, php.depth + 1 AS depth,
COALESCE(php.category_id, (select hcg.id from hivemind_app.hive_category_data hcg where hcg.category = _parent_permlink)) AS category_id,
(CASE(php.root_id)
WHEN 0 THEN php.id
ELSE php.root_id
END) AS root_id,
php.is_valid AS is_valid,
ha.id AS author_id, hpd.id AS permlink_id, _date AS created_at,
_date AS updated_at,
hivemind_app.calculate_time_part_of_hot(_date) AS sc_hot,
hivemind_app.calculate_time_part_of_trending(_date) AS sc_trend,
_date AS active, (_date + INTERVAL '7 days') AS payout_at, (_date + INTERVAL '7 days') AS cashout_time,
0 AS counter_deleted,
_block_num as block_num, _block_num as block_num_created
FROM hivemind_app.hive_accounts ha,
hivemind_app.hive_permlink_data hpd,
hivemind_app.hive_posts php
INNER JOIN hivemind_app.hive_accounts pha ON pha.id = php.author_id
INNER JOIN hivemind_app.hive_permlink_data phpd ON phpd.id = php.permlink_id
WHERE pha.name = _parent_author AND phpd.permlink = _parent_permlink AND
ha.name = _author AND hpd.permlink = _permlink AND php.counter_deleted = 0
) s
SELECT
s.parent_id,
s.depth,
s.community_id,
s.category_id,
s.root_id,
s.is_post_muted,
s.is_valid,
s.author_id,
s.permlink_id,
s.created_at,
s.updated_at,
s.sc_hot,
s.sc_trend,
s.active,
s.payout_at,
s.cashout_time,
s.counter_deleted,
s.block_num,
s.block_num_created,
s.post_muted_reasons
FROM selected_posts AS s
ON CONFLICT ON CONSTRAINT hive_posts_ux1 DO UPDATE SET
--- During post update it is disallowed to change: parent-post, category, community-id
--- then also depth, is_valid and is_muted is impossible to change
--- then also depth, is_valid and is_post_muted is impossible to change
--- post edit part
updated_at = _date,
active = _date,
block_num = _block_num
RETURNING (xmax = 0) as is_new_post, hp.id, hp.author_id, hp.permlink_id, (SELECT hcd.category FROM hivemind_app.hive_category_data hcd WHERE hcd.id = hp.category_id) as post_category, hp.parent_id, hp.community_id, hp.is_valid, hp.is_muted, hp.depth
RETURNING (xmax = 0) as is_new_post, hp.id, hp.author_id, hp.permlink_id, (SELECT hcd.category FROM hivemind_app.hive_category_data hcd WHERE hcd.id = hp.category_id) as post_category, hp.parent_id, (SELECT s.parent_author_id FROM selected_posts AS s) AS parent_author_id, hp.community_id, hp.is_valid, hp.is_muted, hp.depth, (SELECT EXISTS (SELECT NULL::text
FROM hivemind_app.muted AS m
WHERE m.follower = (SELECT s.parent_author_id FROM selected_posts AS s) AND m.following = hp.author_id))
;
ELSE
INSERT INTO hivemind_app.hive_category_data
......@@ -211,7 +241,7 @@ BEGIN
(s.composite).community_id,
s.category_id,
s.root_id,
(s.composite).is_muted,
(s.composite).is_post_muted,
s.is_valid,
s.author_id,
s.permlink_id,
......@@ -225,7 +255,7 @@ BEGIN
s.counter_deleted,
s.block_num,
s.block_num_created,
(s.composite).muted_reasons
(s.composite).post_muted_reasons
FROM (
SELECT
hivemind_app.process_community_post(_block_num, _community_support_start_block, _parent_permlink, ha.id, FALSE,FALSE, NULL) as composite,
......@@ -258,7 +288,7 @@ BEGIN
pdi.community_id,
pdi.category_id,
pdi.root_id,
pdi.is_muted,
pdi.is_post_muted,
pdi.is_valid,
pdi.author_id,
pdi.permlink_id,
......@@ -272,11 +302,11 @@ BEGIN
pdi.counter_deleted,
pdi.block_num,
pdi.block_num_created,
pdi.muted_reasons
pdi.post_muted_reasons
FROM posts_data_to_insert as pdi
ON CONFLICT ON CONSTRAINT hive_posts_ux1 DO UPDATE SET
--- During post update it is disallowed to change: parent-post, category, community-id
--- then also depth, is_valid and is_muted is impossible to change
--- then also depth, is_valid and is_post_muted is impossible to change
--- post edit part
updated_at = _date,
active = _date,
......@@ -309,10 +339,12 @@ BEGIN
ip.permlink_id,
ip.post_category,
ip.parent_id,
0 AS parent_author_id,
ip.community_id,
ip.is_valid,
ip.is_muted,
ip.depth
ip.depth,
FALSE AS is_author_muted
FROM inserted_post as ip;
END IF;
END
......
......@@ -13,9 +13,9 @@ SELECT
FROM hivemind_app.hive_posts hp
;
DROP VIEW IF EXISTS hivemind_app.hive_posts_pp_view CASCADE;
DROP VIEW IF EXISTS hivemind_app.hive_posts_parent_view CASCADE;
CREATE OR REPLACE VIEW hivemind_app.hive_posts_pp_view
CREATE OR REPLACE VIEW hivemind_app.hive_posts_parent_view
AS
SELECT hp.id,
hp.community_id,
......
......@@ -46,7 +46,6 @@ AS $BODY$
$BODY$;
DROP FUNCTION IF EXISTS hivemind_app.notification_id CASCADE;
;
CREATE OR REPLACE FUNCTION hivemind_app.notification_id(in _block_number INTEGER, in _notifyType INTEGER, in _id INTEGER)
RETURNS BIGINT
AS
......@@ -79,11 +78,11 @@ $BODY$;
-- View: hivemind_app.hive_raw_notifications_as_view
-- hive_posts, follows, hive_reblogs, hive_subscriptions, hive_mentions (these are scored by the src account's rank)
DROP VIEW IF EXISTS hivemind_app.hive_raw_notifications_as_view CASCADE;
CREATE OR REPLACE VIEW hivemind_app.hive_raw_notifications_as_view
AS
SELECT notifs.block_num,
notifs.id,
notifs.post_id,
notifs.type_id,
notifs.created_at,
......@@ -94,75 +93,8 @@ CREATE OR REPLACE VIEW hivemind_app.hive_raw_notifications_as_view
notifs.community_title,
notifs.payload,
harv.score
FROM ( SELECT hpv.block_num,
hivemind_app.notification_id(hpv.block_num,
CASE hpv.depth
WHEN 1 THEN 12
ELSE 13
END, hpv.id) AS id,
hpv.id AS post_id,
CASE hpv.depth
WHEN 1 THEN 12
ELSE 13
END AS type_id,
hpv.created_at,
hpv.author_id AS src,
hpv.parent_author_id AS dst,
hpv.parent_id as dst_post_id,
''::character varying(16) AS community,
''::character varying AS community_title,
''::character varying AS payload
FROM hivemind_app.hive_posts_pp_view hpv
WHERE hpv.depth > 0 AND
NOT EXISTS (SELECT NULL::text
FROM hivemind_app.hive_follows hf
WHERE hf.follower = hpv.parent_author_id AND hf.following = hpv.author_id AND hf.state = 2)
UNION ALL
SELECT hf.block_num,
hivemind_app.notification_id(hf.block_num, 15, hf.id) AS id,
0 AS post_id,
15 AS type_id,
(select hb.created_at from hivemind_app.blocks_view hb where hb.num = (hf.block_num - 1)) as created_at, -- use time of previous block to match head_block_time behavior at given block
hf.follower AS src,
hf.following AS dst,
0 as dst_post_id,
''::character varying(16) AS community,
''::character varying AS community_title,
''::character varying AS payload
FROM hivemind_app.hive_follows hf
WHERE hf.state = 1 --only follow blog
UNION ALL
SELECT hr.block_num,
hivemind_app.notification_id(hr.block_num, 14, hr.id) AS id,
hp.id AS post_id,
14 AS type_id,
hr.created_at,
hr.blogger_id AS src,
hp.author_id AS dst,
hr.post_id as dst_post_id,
''::character varying(16) AS community,
''::character varying AS community_title,
''::character varying AS payload
FROM hivemind_app.hive_reblogs hr
JOIN hivemind_app.hive_posts hp ON hr.post_id = hp.id
UNION ALL
SELECT hs.block_num,
hivemind_app.notification_id(hs.block_num, 11, hs.id) AS id,
0 AS post_id,
11 AS type_id,
hs.created_at,
hs.account_id AS src,
hs.community_id AS dst,
0 as dst_post_id,
hc.name AS community,
hc.title AS community_title,
''::character varying AS payload
FROM hivemind_app.hive_subscriptions hs
JOIN hivemind_app.hive_communities hc ON hs.community_id = hc.id
UNION ALL
FROM (
SELECT hm.block_num,
hivemind_app.notification_id(hm.block_num, 16, hm.id) AS id,
hm.post_id,
16 AS type_id,
(select hb.created_at from hivemind_app.blocks_view hb where hb.num = (hm.block_num - 1)) as created_at, -- use time of previous block to match head_block_time behavior at given block
......@@ -172,18 +104,18 @@ UNION ALL
''::character varying(16) AS community,
''::character varying AS community_title,
''::character varying AS payload
FROM hivemind_app.hive_mentions hm
FROM hivemind_app.hive_mentions hm -- mentions
JOIN hivemind_app.hive_posts hp ON hm.post_id = hp.id
) notifs
JOIN hivemind_app.hive_accounts_rank_view harv ON harv.id = notifs.src
;
DROP VIEW IF EXISTS hivemind_app.hive_raw_notifications_view_noas cascade;
CREATE OR REPLACE VIEW hivemind_app.hive_raw_notifications_view_noas
--vote has own score, new communities score as 35 (magic number), persistent notifications are already scored
DROP VIEW IF EXISTS hivemind_app.hive_raw_notifications_view_no_account_score cascade;
CREATE OR REPLACE VIEW hivemind_app.hive_raw_notifications_view_no_account_score
AS
SELECT -- votes
vn.block_num
, vn.id
, vn.post_id
, vn.type_id
, vn.created_at
......@@ -201,7 +133,6 @@ FROM
(
SELECT
hv1.block_num
, hivemind_app.notification_id(hv1.block_num, 17, hv1.id::integer) AS id
, hpv.id AS post_id
, 17 AS type_id
, hv1.last_update AS created_at
......@@ -231,7 +162,6 @@ FROM
UNION ALL
SELECT -- new community
hc.block_num as block_num
, hivemind_app.notification_id(hc.block_num, 11, hc.id) as id
, 0 as post_id
, 1 as type_id
, hc.created_at as created_at
......@@ -247,7 +177,6 @@ UNION ALL
UNION ALL
SELECT --persistent notifs
hn.block_num
, hivemind_app.notification_id(hn.block_num, hn.type_id, CAST( hn.id as INT) ) as id
, hn.post_id as post_id
, hn.type_id as type_id
, hn.created_at as created_at
......@@ -270,6 +199,6 @@ FROM
(
SELECT * FROM hivemind_app.hive_raw_notifications_as_view
UNION ALL
SELECT * FROM hivemind_app.hive_raw_notifications_view_noas
SELECT * FROM hivemind_app.hive_raw_notifications_view_no_account_score
) as notifs
WHERE notifs.score >= 0 AND notifs.src IS DISTINCT FROM notifs.dst;
......@@ -16,11 +16,7 @@ BEGIN
hivemind_postgrest_utilities.parse_argument_from_json(_params, 'observer', True), True),
True);
IF NOT EXISTS (SELECT ha.name FROM hivemind_app.hive_follows hf JOIN hivemind_app.hive_accounts ha ON ha.id = hf.following WHERE hf.follower = _observer_id AND hf.follow_blacklists LIMIT 1) THEN
RETURN 'false'::jsonb;
ELSE
RETURN 'true'::jsonb;
END IF;
RETURN (SELECT EXISTS (SELECT ha.name FROM hivemind_app.follow_blacklisted fb JOIN hivemind_app.hive_accounts ha ON ha.id = fb.following WHERE fb.follower = _observer_id LIMIT 1))::TEXT::jsonb;
END
$$
;
\ No newline at end of file
;
......@@ -42,16 +42,25 @@ BEGIN
IF _get_blacklists THEN
_result = (
WITH np AS ( -- bridge_api_get_follow_list with _get_blacklists
SELECT
SELECT
ha.name,
hivemind_postgrest_utilities.extract_profile_metadata(ha.json_metadata, ha.posting_json_metadata)->'profile' AS profile
FROM
hivemind_app.hive_follows hf
hivemind_app.follow_muted AS fm
JOIN
hivemind_app.hive_accounts ha ON ha.id = hf.following
hivemind_app.hive_accounts ha ON ha.id = fm.following
WHERE
hf.follower = _observer_id AND
(CASE WHEN _follow_muted THEN hf.follow_muted ELSE hf.follow_blacklists END)
fm.follower = _observer_id AND _follow_muted
UNION ALL
SELECT
ha.name,
hivemind_postgrest_utilities.extract_profile_metadata(ha.json_metadata, ha.posting_json_metadata)->'profile' AS profile
FROM
hivemind_app.follow_blacklisted AS fb
JOIN
hivemind_app.hive_accounts ha ON ha.id = fb.following
WHERE
fb.follower = _observer_id AND NOT _follow_muted
)
SELECT jsonb_agg(
jsonb_build_object(
......@@ -70,16 +79,16 @@ BEGIN
'muted_list_description', to_jsonb(''::TEXT)
)
) FROM (
SELECT
ha.name
FROM
hivemind_app.hive_follows hf
JOIN
hivemind_app.hive_accounts ha ON ha.id = hf.following
WHERE
hf.follower = _observer_id AND
(CASE WHEN _follow_muted THEN hf.state = 2 ELSE hf.blacklisted END)
ORDER BY ha.name
SELECT ha.name
FROM hivemind_app.muted AS m
JOIN hivemind_app.hive_accounts ha ON ha.id = m.following
WHERE m.follower = _observer_id AND _follow_muted
UNION ALL
SELECT ha.name
FROM hivemind_app.blacklisted AS b
JOIN hivemind_app.hive_accounts ha ON ha.id = b.following
WHERE b.follower = _observer_id AND NOT _follow_muted
ORDER BY name
) row
);
END IF;
......@@ -87,4 +96,4 @@ BEGIN
RETURN COALESCE(_result, '[]'::jsonb);
END
$$
;
\ No newline at end of file
;
......@@ -26,7 +26,7 @@ BEGIN
hivemind_postgrest_utilities.parse_argument_from_json(_params, 'account2', True),
False),
True);
_observer_id = hivemind_postgrest_utilities.find_account_id(
hivemind_postgrest_utilities.valid_account(
hivemind_postgrest_utilities.parse_argument_from_json(_params, 'observer', False),
......@@ -35,63 +35,13 @@ BEGIN
_debug = hivemind_postgrest_utilities.parse_argument_from_json(_params, 'debug', False);
IF _debug IS NULL THEN
_debug = False;
END IF;
RETURN COALESCE(
( SELECT
CASE WHEN NOT _debug THEN
jsonb_build_object( -- bridge_api_get_relationship_between_accounts
'follows', CASE WHEN row.state = 1 THEN TRUE ELSE FALSE END,
'ignores', CASE WHEN row.state = 2 THEN TRUE ELSE FALSE END,
'blacklists', row.blacklisted,
'follows_blacklists', row.follow_blacklists,
'follows_muted', row.follow_muted
) ELSE
jsonb_build_object( -- bridge_api_get_relationship_between_accounts with debug
'follows', CASE WHEN row.state = 1 THEN TRUE ELSE FALSE END,
'ignores', CASE WHEN row.state = 2 THEN TRUE ELSE FALSE END,
'blacklists', row.blacklisted,
'follows_blacklists', row.follow_blacklists,
'follows_muted', row.follow_muted,
'created_at', COALESCE(to_char(row.created_at, 'YYYY-MM-DD"T"HH24:MI:SS'), NULL),
'block_num', row.block_num
)
END
FROM (
SELECT
hf.state,
COALESCE(hf.blacklisted, False) AS blacklisted,
COALESCE(hf.follow_blacklists, FALSE) AS follow_blacklists,
COALESCE(hf.follow_muted, FALSE) AS follow_muted,
hf.created_at,
hf.block_num
FROM
hivemind_app.hive_follows hf
WHERE
hf.follower = _account1_id AND hf.following = _account2_id
LIMIT 1
) row ),
CASE WHEN NOT _debug THEN
jsonb_build_object( -- bridge_api_get_relationship_between_accounts null
'follows', FALSE,
'ignores', FALSE,
'blacklists', FALSE,
'follows_blacklists', FALSE,
'follows_muted', FALSE
) ELSE
jsonb_build_object( -- bridge_api_get_relationship_between_accounts null with debug
'follows', FALSE,
'ignores', FALSE,
'blacklists', FALSE,
'follows_blacklists', FALSE,
'follows_muted', FALSE,
'created_at', NULL,
'block_num', NULL
)
END
RETURN jsonb_build_object(
'follows', (SELECT EXISTS (SELECT 1 FROM hivemind_app.follows WHERE follower=_account1_id AND FOLLOWING=_account2_id)),
'ignores', (SELECT EXISTS (SELECT 1 FROM hivemind_app.muted WHERE follower=_account1_id AND FOLLOWING=_account2_id)),
'blacklists', (SELECT EXISTS (SELECT 1 FROM hivemind_app.blacklisted WHERE follower=_account1_id AND FOLLOWING=_account2_id)),
'follows_blacklists', (SELECT EXISTS (SELECT 1 FROM hivemind_app.follow_blacklisted WHERE follower=_account1_id AND FOLLOWING=_account2_id)),
'follows_muted', (SELECT EXISTS (SELECT 1 FROM hivemind_app.follow_muted WHERE follower=_account1_id AND FOLLOWING=_account2_id))
);
END
$$
;
\ No newline at end of file
;
......@@ -6,23 +6,15 @@ STABLE
AS
$$
DECLARE
_start_id INT DEFAULT 2147483647; --default to max allowed INT value to get the latest followers if _start_id is set to 0
_start TEXT DEFAULT '';
_account_id INT;
_state SMALLINT;
_limit INT;
BEGIN
_params = hivemind_postgrest_utilities.extract_parameters_for_get_following_and_followers(_params, _called_from_condenser_api);
_account_id = (_params->'account_id')::INT;
_state = (_params->'hive_follows_state')::SMALLINT;
_limit = (_params->'limit')::INT;
IF (_params->'start_id')::INT <> 0 THEN
_start_id = (
SELECT hf.id
FROM hivemind_app.hive_follows hf
WHERE hf.following = (_params->'account_id')::INT AND hf.follower = (_params->'start_id')::INT
);
END IF;
_start = (_params->>'start')::TEXT;
RETURN COALESCE(
(
......@@ -32,26 +24,30 @@ BEGIN
'follower', row.name,
'what', jsonb_build_array(_params->'follow_type')
)
ORDER BY row.id DESC
)
ORDER BY row.name
)
FROM (
WITH followers AS MATERIALIZED
(
SELECT
hf.id,
hf.follower
FROM hivemind_app.hive_follows hf
WHERE hf.following = _account_id AND hf.state = _state -- hive_follows_following_state_id_idx
AND hf.id < _start_id
ORDER BY hf.id DESC
SELECT ha.name
FROM hivemind_app.follows AS f
JOIN hivemind_app.hive_accounts AS ha ON f.follower = ha.id
WHERE f.following = _account_id
AND (_start = '' OR ha.name > _start)
AND (_params->'follows')::boolean
UNION ALL
SELECT ha.name
FROM hivemind_app.muted AS m
JOIN hivemind_app.hive_accounts AS ha ON m.follower = ha.id
WHERE m.following = _account_id
AND (_start = '' OR ha.name > _start)
AND (_params->'mutes')::boolean
ORDER BY name
LIMIT _limit
)
SELECT
followers.id,
ha.name
)
SELECT name
FROM followers
JOIN hivemind_app.hive_accounts ha ON followers.follower = ha.id
ORDER BY followers.id DESC
ORDER BY name
LIMIT _limit
) row
),
......
......@@ -6,17 +6,10 @@ STABLE
AS
$$
DECLARE
_start_id INT DEFAULT 0;
_start TEXT DEFAULT '';
BEGIN
_params = hivemind_postgrest_utilities.extract_parameters_for_get_following_and_followers(_params, _called_from_condenser_api);
IF (_params->'start_id')::INT <> 0 THEN
_start_id = (
SELECT hf.id
FROM hivemind_app.hive_follows hf
WHERE hf.follower = (_params->'account_id')::INT AND hf.following = (_params->'start_id')::INT
);
END IF;
_start = (_params->>'start')::TEXT;
RETURN COALESCE(
(
......@@ -26,37 +19,44 @@ BEGIN
'follower', _params->>'account',
'what', jsonb_build_array(_params->>'follow_type')
)
ORDER BY row.id DESC
ORDER BY row.name
) FROM (
WITH
max_10k_following AS
WITH
max_10k_follows AS
(
SELECT
hf.id,
hf.following
FROM hivemind_app.hive_follows hf
WHERE -- INDEX ONLY SCAN of hive_follows_follower_following_state_idx
hf.state = (_params->'hive_follows_state')::SMALLINT
AND hf.follower = (_params->'account_id')::INT
f.following
FROM hivemind_app.follows AS f
WHERE
f.follower = (_params->'account_id')::INT
LIMIT 10000 -- if user follows more than 10K accounts, limit them
),
following_page AS -- condenser_api_get_following
),
max_10k_mutes AS
(
SELECT
hf.id,
hf.following
FROM max_10k_following hf
m.following
FROM hivemind_app.muted AS m
WHERE
(_start_id = 0 OR hf.id < _start_id)
ORDER BY hf.id DESC
m.follower = (_params->'account_id')::INT
LIMIT 10000 -- if user ignores more than 10K accounts, limit them
),
following_page AS -- condenser_api_get_following
(
SELECT ha.name
FROM max_10k_follows AS f
JOIN hivemind_app.hive_accounts AS ha ON f.following = ha.id
WHERE (_start = '' OR ha.name > _start) AND (_params->'follows')::boolean
UNION ALL
SELECT ha.name
FROM max_10k_mutes AS m
JOIN hivemind_app.hive_accounts AS ha ON m.following = ha.id
WHERE (_start = '' OR ha.name > _start) AND (_params->'mutes')::boolean
ORDER BY name
LIMIT (_params->'limit')::INT
)
SELECT
fs.id,
ha.name
SELECT name
FROM following_page fs
JOIN hivemind_app.hive_accounts ha ON fs.following = ha.id
ORDER BY fs.id DESC
ORDER BY name
LIMIT (_params->'limit')::INT
) row
),
......
......@@ -8,7 +8,7 @@ $$
DECLARE
_account TEXT;
_account_id INT;
_start_id INT;
_start TEXT;
_limit INT;
_follow_type TEXT;
_hive_follows_state INT;
......@@ -27,12 +27,11 @@ BEGIN
_account_id = hivemind_postgrest_utilities.find_account_id(_account, True);
_start_id =
hivemind_postgrest_utilities.find_account_id(
hivemind_postgrest_utilities.valid_account(
hivemind_postgrest_utilities.parse_argument_from_json(_params, 'start', False),
True),
_start =
hivemind_postgrest_utilities.valid_account(
hivemind_postgrest_utilities.parse_argument_from_json(_params, 'start', False),
True);
PERFORM hivemind_postgrest_utilities.find_account_id(_start, True); -- make sure account exists
IF _called_from_condenser_api THEN
_follow_type = COALESCE(hivemind_postgrest_utilities.parse_argument_from_json(_params, 'follow_type', False), 'blog');
......@@ -40,11 +39,7 @@ BEGIN
_follow_type = COALESCE(hivemind_postgrest_utilities.parse_argument_from_json(_params, 'type', False), 'blog');
END IF;
IF _follow_type = 'blog' THEN
_hive_follows_state = 1;
ELSIF _follow_type = 'ignore' THEN
_hive_follows_state = 2;
ELSE
IF _follow_type NOT IN ('blog', 'ignore') THEN
RAISE EXCEPTION '%', hivemind_postgrest_utilities.raise_parameter_validation_exception('Unsupported follow type, valid types: blog, ignore');
END IF;
......@@ -56,11 +51,12 @@ BEGIN
RETURN jsonb_build_object(
'account', _account,
'account_id', _account_id,
'start_id', _start_id,
'start', COALESCE(_start, ''),
'limit', _limit,
'follow_type', _follow_type,
'hive_follows_state', _hive_follows_state
'follows', _follow_type = 'blog',
'mutes', _follow_type = 'ignore'
);
END
$$
;
\ No newline at end of file
;
......@@ -204,8 +204,8 @@ BEGIN
IF _post_id <> 0 THEN
SELECT MIN(hfc.created_at) INTO _min_date
FROM hivemind_app.hive_feed_cache hfc
JOIN hivemind_app.hive_follows hf ON hfc.account_id = hf.following
WHERE hf.state = 1 AND hf.follower = _account_id AND hfc.post_id = _post_id;
JOIN hivemind_app.follows f ON hfc.account_id = f.following
WHERE f.follower = _account_id AND hfc.post_id = _post_id;
END IF;
_cutoff = hivemind_app.block_before_head( '1 month' );
......@@ -227,9 +227,9 @@ BEGIN
MIN(hfc.created_at) as min_created,
array_agg(DISTINCT(ha.name) ORDER BY ha.name) AS reblogged_by
FROM hivemind_app.hive_feed_cache hfc
JOIN hivemind_app.hive_follows hf ON hfc.account_id = hf.following
JOIN hivemind_app.hive_accounts ha ON ha.id = hf.following
WHERE hfc.block_num > _cutoff AND hf.state = 1 AND hf.follower = _account_id
JOIN hivemind_app.follows f ON hfc.account_id = f.following
JOIN hivemind_app.hive_accounts ha ON ha.id = f.following
WHERE hfc.block_num > _cutoff AND f.follower = _account_id
AND (_observer_id = 0 OR NOT EXISTS (SELECT 1 FROM hivemind_app.muted_accounts_by_id_view WHERE observer_id = _observer_id AND muted_id = hfc.account_id))
GROUP BY hfc.post_id
HAVING (_post_id = 0 OR MIN(hfc.created_at) < _min_date OR ( MIN(hfc.created_at) = _min_date AND hfc.post_id < _post_id ))
......