mirror of
https://github.com/simple-login/app.git
synced 2025-02-25 08:13:16 +08:00
create get_alias_infos_with_pagination_v3 - reduce nb queries used in get_alias_infos_with_pagination_v2
This commit is contained in:
parent
06c48244e4
commit
30fe09185f
4 changed files with 107 additions and 6 deletions
|
@ -1,7 +1,7 @@
|
|||
from dataclasses import dataclass
|
||||
|
||||
from arrow import Arrow
|
||||
from sqlalchemy import or_, func, case
|
||||
from sqlalchemy import or_, func, case, and_
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
from app.config import PAGE_LIMIT
|
||||
|
@ -186,6 +186,106 @@ def get_alias_infos_with_pagination_v2(
|
|||
return ret
|
||||
|
||||
|
||||
def get_alias_infos_with_pagination_v3(
|
||||
user, page_id=0, query=None, sort=None, alias_filter=None
|
||||
) -> [AliasInfo]:
|
||||
ret = []
|
||||
latest_activity = func.max(
|
||||
case(
|
||||
[
|
||||
(Alias.created_at > EmailLog.created_at, Alias.created_at),
|
||||
(Alias.created_at < EmailLog.created_at, EmailLog.created_at),
|
||||
],
|
||||
else_=Alias.created_at,
|
||||
)
|
||||
).label("latest")
|
||||
|
||||
sub = (
|
||||
db.session.query(
|
||||
Alias.id,
|
||||
latest_activity,
|
||||
func.sum(case([(EmailLog.is_reply, 1)], else_=0)).label("nb_reply"),
|
||||
func.sum(
|
||||
case(
|
||||
[(and_(EmailLog.is_reply == False, EmailLog.blocked), 1)], else_=0,
|
||||
)
|
||||
).label("nb_blocked"),
|
||||
func.sum(
|
||||
case(
|
||||
[
|
||||
(
|
||||
and_(
|
||||
EmailLog.is_reply == False, EmailLog.blocked == False,
|
||||
),
|
||||
1,
|
||||
)
|
||||
],
|
||||
else_=0,
|
||||
)
|
||||
).label("nb_forward"),
|
||||
func.max(EmailLog.created_at).label("max_created_at"),
|
||||
)
|
||||
.join(Contact, Alias.id == Contact.alias_id, isouter=True)
|
||||
.join(EmailLog, Contact.id == EmailLog.contact_id, isouter=True)
|
||||
.filter(Alias.user_id == user.id)
|
||||
.group_by(Alias.id)
|
||||
.subquery()
|
||||
)
|
||||
|
||||
q = db.session.query(
|
||||
Alias, Contact, EmailLog, sub.c.nb_reply, sub.c.nb_blocked, sub.c.nb_forward
|
||||
).filter(
|
||||
Alias.id == sub.c.id,
|
||||
Alias.id == Contact.alias_id,
|
||||
Contact.id == EmailLog.contact_id,
|
||||
EmailLog.created_at == sub.c.latest,
|
||||
)
|
||||
|
||||
if query:
|
||||
q = q.filter(
|
||||
or_(
|
||||
Alias.email.ilike(f"%{query}%"),
|
||||
Alias.note.ilike(f"%{query}%"),
|
||||
Alias.name.ilike(f"%{query}%"),
|
||||
)
|
||||
)
|
||||
|
||||
if alias_filter == "enabled":
|
||||
q = q.filter(Alias.enabled)
|
||||
elif alias_filter == "disabled":
|
||||
q = q.filter(Alias.enabled == False)
|
||||
|
||||
if sort == "old2new":
|
||||
q = q.order_by(Alias.created_at)
|
||||
elif sort == "new2old":
|
||||
q = q.order_by(Alias.created_at.desc())
|
||||
elif sort == "a2z":
|
||||
q = q.order_by(Alias.email)
|
||||
elif sort == "z2a":
|
||||
q = q.order_by(Alias.email.desc())
|
||||
else:
|
||||
# default sorting
|
||||
q = q.order_by(sub.c.latest.desc())
|
||||
|
||||
q = list(q.limit(PAGE_LIMIT).offset(page_id * PAGE_LIMIT))
|
||||
|
||||
for alias, contact, email_log, nb_reply, nb_blocked, nb_forward in q:
|
||||
ret.append(
|
||||
AliasInfo(
|
||||
alias=alias,
|
||||
mailbox=alias.mailbox,
|
||||
mailboxes=alias.mailboxes,
|
||||
nb_forward=nb_forward,
|
||||
nb_blocked=nb_blocked,
|
||||
nb_reply=nb_reply,
|
||||
latest_email_log=email_log,
|
||||
latest_contact=contact,
|
||||
)
|
||||
)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def get_alias_info(alias: Alias) -> AliasInfo:
|
||||
q = (
|
||||
db.session.query(Contact, EmailLog)
|
||||
|
|
|
@ -10,9 +10,9 @@ from app.api.serializer import (
|
|||
serialize_contact,
|
||||
get_alias_infos_with_pagination,
|
||||
get_alias_contacts,
|
||||
get_alias_infos_with_pagination_v2,
|
||||
serialize_alias_info_v2,
|
||||
get_alias_info_v2,
|
||||
get_alias_infos_with_pagination_v3,
|
||||
)
|
||||
from app.config import EMAIL_DOMAIN
|
||||
from app.dashboard.views.alias_log import get_alias_log
|
||||
|
@ -107,7 +107,7 @@ def get_aliases_v2():
|
|||
if data:
|
||||
query = data.get("query")
|
||||
|
||||
alias_infos: [AliasInfo] = get_alias_infos_with_pagination_v2(
|
||||
alias_infos: [AliasInfo] = get_alias_infos_with_pagination_v3(
|
||||
user, page_id=page_id, query=query
|
||||
)
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@
|
|||
{% set alias = alias_info.alias %}
|
||||
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card p-4 shadow-sm {% if alias_info.alias.id == highlight_alias_id %} highlight-row {% endif %} ">
|
||||
<div class="card p-4 shadow-sm {% if alias.id == highlight_alias_id %} highlight-row {% endif %} ">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
from dataclasses import dataclass
|
||||
|
||||
from flask import render_template, request, redirect, url_for, flash
|
||||
from flask_login import login_required, current_user
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
from app import alias_utils
|
||||
from app.api.serializer import get_alias_infos_with_pagination_v2
|
||||
from app.api.serializer import get_alias_infos_with_pagination_v3
|
||||
from app.config import PAGE_LIMIT
|
||||
from app.dashboard.base import dashboard_bp
|
||||
from app.extensions import db
|
||||
|
@ -136,7 +137,7 @@ def index():
|
|||
|
||||
stats = get_stats(current_user)
|
||||
|
||||
alias_infos = get_alias_infos_with_pagination_v2(
|
||||
alias_infos = get_alias_infos_with_pagination_v3(
|
||||
current_user, page, query, sort, alias_filter
|
||||
)
|
||||
last_page = len(alias_infos) < PAGE_LIMIT
|
||||
|
|
Loading…
Reference in a new issue