This commit is contained in:
parent
f9a91e3a66
commit
9c374d789e
|
@ -38,7 +38,7 @@ class Reaction(Base):
|
||||||
deleted_by = Column(ForeignKey("author.id"), nullable=True)
|
deleted_by = Column(ForeignKey("author.id"), nullable=True)
|
||||||
reply_to = Column(ForeignKey("reaction.id"), nullable=True)
|
reply_to = Column(ForeignKey("reaction.id"), nullable=True)
|
||||||
quote = Column(String, nullable=True, comment="Original quoted text")
|
quote = Column(String, nullable=True, comment="Original quoted text")
|
||||||
shout = Column(ForeignKey("shout.id"), nullable=False)
|
shout = Column(ForeignKey("shout.id"), nullable=False, index=True)
|
||||||
created_by = Column(ForeignKey("author.id"), nullable=False)
|
created_by = Column(ForeignKey("author.id"), nullable=False)
|
||||||
kind = Column(String, nullable=False, index=True)
|
kind = Column(String, nullable=False, index=True)
|
||||||
|
|
||||||
|
|
|
@ -27,43 +27,49 @@ from services.viewed import ViewedStorage
|
||||||
|
|
||||||
def query_shouts():
|
def query_shouts():
|
||||||
"""
|
"""
|
||||||
Базовый запрос для получения публикаций с подзапросами статистики, авторов и тем.
|
Базовый запрос для получения публикаций с подзапросами статистики, авторов и тем,
|
||||||
|
с агрегацией в строку вместо JSON.
|
||||||
|
|
||||||
|
:param session: Сессия SQLAlchemy для выполнения запроса.
|
||||||
:return: Запрос для получения публикаций.
|
:return: Запрос для получения публикаций.
|
||||||
"""
|
"""
|
||||||
# Создаем алиасы для таблиц для избежания конфликтов имен
|
# Создаем алиасы для таблиц для избежания конфликтов имен
|
||||||
aliased_reaction = aliased(Reaction)
|
aliased_reaction = aliased(Reaction)
|
||||||
|
|
||||||
# Подзапрос для уникальных авторов
|
# Подзапрос для уникальных авторов, объединенных в строку
|
||||||
authors_subquery = (
|
authors_subquery = (
|
||||||
select(
|
select(
|
||||||
ShoutAuthor.shout.label("shout_id"),
|
ShoutAuthor.shout.label("shout_id"),
|
||||||
func.json_agg(
|
func.string_agg(
|
||||||
func.json_build_object(
|
func.concat_ws(
|
||||||
'id', Author.id,
|
";",
|
||||||
'name', Author.name,
|
func.concat("id:", Author.id),
|
||||||
'slug', Author.slug,
|
func.concat("name:", Author.name),
|
||||||
'pic', Author.pic
|
func.concat("slug:", Author.slug),
|
||||||
)
|
func.concat("pic:", Author.pic),
|
||||||
).label("authors")
|
),
|
||||||
|
", ",
|
||||||
|
).label("authors"),
|
||||||
)
|
)
|
||||||
.join(Author, ShoutAuthor.author == Author.id)
|
.join(Author, ShoutAuthor.author == Author.id)
|
||||||
.group_by(ShoutAuthor.shout)
|
.group_by(ShoutAuthor.shout)
|
||||||
.subquery()
|
.subquery()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Подзапрос для уникальных тем
|
# Подзапрос для уникальных тем, объединенных в строку
|
||||||
topics_subquery = (
|
topics_subquery = (
|
||||||
select(
|
select(
|
||||||
ShoutTopic.shout.label("shout_id"),
|
ShoutTopic.shout.label("shout_id"),
|
||||||
func.json_agg(
|
func.string_agg(
|
||||||
func.json_build_object(
|
func.concat_ws(
|
||||||
'id', Topic.id,
|
";",
|
||||||
'title', Topic.title,
|
func.concat("id:", Topic.id),
|
||||||
'body', Topic.body,
|
func.concat("title:", Topic.title),
|
||||||
'slug', Topic.slug
|
func.concat("body:", Topic.body),
|
||||||
)
|
func.concat("slug:", Topic.slug),
|
||||||
).label("topics")
|
),
|
||||||
|
", ",
|
||||||
|
).label("topics"),
|
||||||
)
|
)
|
||||||
.join(Topic, ShoutTopic.topic == Topic.id)
|
.join(Topic, ShoutTopic.topic == Topic.id)
|
||||||
.group_by(ShoutTopic.shout)
|
.group_by(ShoutTopic.shout)
|
||||||
|
@ -95,6 +101,7 @@ def query_shouts():
|
||||||
|
|
||||||
return q, aliased_reaction
|
return q, aliased_reaction
|
||||||
|
|
||||||
|
|
||||||
def get_shouts_with_stats(q, limit, offset=0, author_id=None):
|
def get_shouts_with_stats(q, limit, offset=0, author_id=None):
|
||||||
"""
|
"""
|
||||||
Получение публикаций со статистикой, и подзапросами авторов и тем.
|
Получение публикаций со статистикой, и подзапросами авторов и тем.
|
||||||
|
|
|
@ -12,21 +12,23 @@ from cache.memorycache import cache_region
|
||||||
from services.schema import mutation, query
|
from services.schema import mutation, query
|
||||||
|
|
||||||
|
|
||||||
|
# Запрос на получение всех тем
|
||||||
@query.field("get_topics_all")
|
@query.field("get_topics_all")
|
||||||
def get_topics_all(_, _info):
|
def get_topics_all(_, _info):
|
||||||
cache_key = "get_topics_all"
|
cache_key = "get_topics_all" # Ключ для кеша
|
||||||
|
|
||||||
@cache_region.cache_on_arguments(cache_key)
|
@cache_region.cache_on_arguments(cache_key)
|
||||||
def _get_topics_all():
|
def _get_topics_all():
|
||||||
topics_query = select(Topic)
|
topics_query = select(Topic)
|
||||||
return get_with_stat(topics_query)
|
return get_with_stat(topics_query) # Получение тем с учетом статистики
|
||||||
|
|
||||||
return _get_topics_all()
|
return _get_topics_all()
|
||||||
|
|
||||||
|
|
||||||
|
# Запрос на получение тем по сообществу
|
||||||
@query.field("get_topics_by_community")
|
@query.field("get_topics_by_community")
|
||||||
def get_topics_by_community(_, _info, community_id: int):
|
def get_topics_by_community(_, _info, community_id: int):
|
||||||
cache_key = f"get_topics_by_community_{community_id}"
|
cache_key = f"get_topics_by_community_{community_id}" # Ключ для кеша
|
||||||
|
|
||||||
@cache_region.cache_on_arguments(cache_key)
|
@cache_region.cache_on_arguments(cache_key)
|
||||||
def _get_topics_by_community():
|
def _get_topics_by_community():
|
||||||
|
@ -36,6 +38,7 @@ def get_topics_by_community(_, _info, community_id: int):
|
||||||
return _get_topics_by_community()
|
return _get_topics_by_community()
|
||||||
|
|
||||||
|
|
||||||
|
# Запрос на получение тем по автору
|
||||||
@query.field("get_topics_by_author")
|
@query.field("get_topics_by_author")
|
||||||
async def get_topics_by_author(_, _info, author_id=0, slug="", user=""):
|
async def get_topics_by_author(_, _info, author_id=0, slug="", user=""):
|
||||||
topics_by_author_query = select(Topic)
|
topics_by_author_query = select(Topic)
|
||||||
|
@ -49,6 +52,7 @@ async def get_topics_by_author(_, _info, author_id=0, slug="", user=""):
|
||||||
return get_with_stat(topics_by_author_query)
|
return get_with_stat(topics_by_author_query)
|
||||||
|
|
||||||
|
|
||||||
|
# Запрос на получение одной темы по её slug
|
||||||
@query.field("get_topic")
|
@query.field("get_topic")
|
||||||
async def get_topic(_, _info, slug: str):
|
async def get_topic(_, _info, slug: str):
|
||||||
topic = await get_cached_topic_by_slug(slug, get_with_stat)
|
topic = await get_cached_topic_by_slug(slug, get_with_stat)
|
||||||
|
@ -56,12 +60,13 @@ async def get_topic(_, _info, slug: str):
|
||||||
return topic
|
return topic
|
||||||
|
|
||||||
|
|
||||||
|
# Мутация для создания новой темы
|
||||||
@mutation.field("create_topic")
|
@mutation.field("create_topic")
|
||||||
@login_required
|
@login_required
|
||||||
async def create_topic(_, _info, inp):
|
async def create_topic(_, _info, inp):
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
# TODO: check user permissions to create topic for exact community
|
# TODO: проверить права пользователя на создание темы для конкретного сообщества
|
||||||
# and actor is permitted to craete it
|
# и разрешение на создание
|
||||||
new_topic = Topic(**inp)
|
new_topic = Topic(**inp)
|
||||||
session.add(new_topic)
|
session.add(new_topic)
|
||||||
session.commit()
|
session.commit()
|
||||||
|
@ -69,6 +74,7 @@ async def create_topic(_, _info, inp):
|
||||||
return {"topic": new_topic}
|
return {"topic": new_topic}
|
||||||
|
|
||||||
|
|
||||||
|
# Мутация для обновления темы
|
||||||
@mutation.field("update_topic")
|
@mutation.field("update_topic")
|
||||||
@login_required
|
@login_required
|
||||||
async def update_topic(_, _info, inp):
|
async def update_topic(_, _info, inp):
|
||||||
|
@ -85,6 +91,7 @@ async def update_topic(_, _info, inp):
|
||||||
return {"topic": topic}
|
return {"topic": topic}
|
||||||
|
|
||||||
|
|
||||||
|
# Мутация для удаления темы
|
||||||
@mutation.field("delete_topic")
|
@mutation.field("delete_topic")
|
||||||
@login_required
|
@login_required
|
||||||
async def delete_topic(_, info, slug: str):
|
async def delete_topic(_, info, slug: str):
|
||||||
|
@ -105,6 +112,7 @@ async def delete_topic(_, info, slug: str):
|
||||||
return {"error": "access denied"}
|
return {"error": "access denied"}
|
||||||
|
|
||||||
|
|
||||||
|
# Запрос на получение случайных тем
|
||||||
@query.field("get_topics_random")
|
@query.field("get_topics_random")
|
||||||
def get_topics_random(_, _info, amount=12):
|
def get_topics_random(_, _info, amount=12):
|
||||||
q = select(Topic)
|
q = select(Topic)
|
||||||
|
@ -121,6 +129,7 @@ def get_topics_random(_, _info, amount=12):
|
||||||
return topics
|
return topics
|
||||||
|
|
||||||
|
|
||||||
|
# Запрос на получение подписчиков темы
|
||||||
@query.field("get_topic_followers")
|
@query.field("get_topic_followers")
|
||||||
async def get_topic_followers(_, _info, slug: str):
|
async def get_topic_followers(_, _info, slug: str):
|
||||||
logger.debug(f"getting followers for @{slug}")
|
logger.debug(f"getting followers for @{slug}")
|
||||||
|
@ -130,6 +139,7 @@ async def get_topic_followers(_, _info, slug: str):
|
||||||
return followers
|
return followers
|
||||||
|
|
||||||
|
|
||||||
|
# Запрос на получение авторов темы
|
||||||
@query.field("get_topic_authors")
|
@query.field("get_topic_authors")
|
||||||
async def get_topic_authors(_, _info, slug: str):
|
async def get_topic_authors(_, _info, slug: str):
|
||||||
logger.debug(f"getting authors for @{slug}")
|
logger.debug(f"getting authors for @{slug}")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user