mirror of
https://github.com/simple-login/app.git
synced 2025-02-25 16:23: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 dataclasses import dataclass
|
||||||
|
|
||||||
from arrow import Arrow
|
from arrow import Arrow
|
||||||
from sqlalchemy import or_, func, case
|
from sqlalchemy import or_, func, case, and_
|
||||||
from sqlalchemy.orm import joinedload
|
from sqlalchemy.orm import joinedload
|
||||||
|
|
||||||
from app.config import PAGE_LIMIT
|
from app.config import PAGE_LIMIT
|
||||||
|
@ -186,6 +186,106 @@ def get_alias_infos_with_pagination_v2(
|
||||||
return ret
|
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:
|
def get_alias_info(alias: Alias) -> AliasInfo:
|
||||||
q = (
|
q = (
|
||||||
db.session.query(Contact, EmailLog)
|
db.session.query(Contact, EmailLog)
|
||||||
|
|
|
@ -10,9 +10,9 @@ from app.api.serializer import (
|
||||||
serialize_contact,
|
serialize_contact,
|
||||||
get_alias_infos_with_pagination,
|
get_alias_infos_with_pagination,
|
||||||
get_alias_contacts,
|
get_alias_contacts,
|
||||||
get_alias_infos_with_pagination_v2,
|
|
||||||
serialize_alias_info_v2,
|
serialize_alias_info_v2,
|
||||||
get_alias_info_v2,
|
get_alias_info_v2,
|
||||||
|
get_alias_infos_with_pagination_v3,
|
||||||
)
|
)
|
||||||
from app.config import EMAIL_DOMAIN
|
from app.config import EMAIL_DOMAIN
|
||||||
from app.dashboard.views.alias_log import get_alias_log
|
from app.dashboard.views.alias_log import get_alias_log
|
||||||
|
@ -107,7 +107,7 @@ def get_aliases_v2():
|
||||||
if data:
|
if data:
|
||||||
query = data.get("query")
|
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
|
user, page_id=page_id, query=query
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,7 @@
|
||||||
{% set alias = alias_info.alias %}
|
{% set alias = alias_info.alias %}
|
||||||
|
|
||||||
<div class="col-12 col-lg-6">
|
<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="row">
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
from flask import render_template, request, redirect, url_for, flash
|
from flask import render_template, request, redirect, url_for, flash
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
from sqlalchemy.orm import joinedload
|
from sqlalchemy.orm import joinedload
|
||||||
|
|
||||||
from app import alias_utils
|
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.config import PAGE_LIMIT
|
||||||
from app.dashboard.base import dashboard_bp
|
from app.dashboard.base import dashboard_bp
|
||||||
from app.extensions import db
|
from app.extensions import db
|
||||||
|
@ -136,7 +137,7 @@ def index():
|
||||||
|
|
||||||
stats = get_stats(current_user)
|
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
|
current_user, page, query, sort, alias_filter
|
||||||
)
|
)
|
||||||
last_page = len(alias_infos) < PAGE_LIMIT
|
last_page = len(alias_infos) < PAGE_LIMIT
|
||||||
|
|
Loading…
Reference in a new issue