remove 'ilike' for most case insensitive searches - too slow

This commit is contained in:
rimu 2024-02-09 14:58:51 +13:00
parent 321a95b59b
commit 45d8b042a5
3 changed files with 12 additions and 11 deletions

View file

@ -6,7 +6,7 @@ from datetime import timedelta
from random import randint
from typing import Union, Tuple
from flask import current_app, request, g, url_for
from sqlalchemy import text
from sqlalchemy import text, func
from app import db, cache, constants, celery
from app.models import User, Post, Community, BannedInstances, File, PostReply, AllowedInstances, Instance, utcnow, \
PostVote, PostReplyVote, ActivityPubLog, Notification, Site, CommunityMember
@ -189,10 +189,10 @@ def find_actor_or_create(actor: str) -> Union[User, Community, None]:
# Initially, check if the user exists in the local DB already
if current_app.config['SERVER_NAME'] + '/c/' in actor:
return Community.query.filter(Community.ap_profile_id.ilike(actor)).first() # finds communities formatted like https://localhost/c/*
return Community.query.filter(func.lower(Community.ap_profile_id) == func.lower(actor)).first() # finds communities formatted like https://localhost/c/*
if current_app.config['SERVER_NAME'] + '/u/' in actor:
user = User.query.filter(User.user_name.ilike(actor.split('/')[-1])).filter_by(ap_id=None, banned=False).first() # finds local users
user = User.query.filter(func.lower(User.user_name) == func.lower(actor.split('/')[-1])).filter_by(ap_id=None, banned=False).first() # finds local users
if user is None:
return None
elif actor.startswith('https://'):
@ -203,11 +203,11 @@ def find_actor_or_create(actor: str) -> Union[User, Community, None]:
else:
if instance_blocked(server):
return None
user = User.query.filter(User.ap_profile_id.ilike(actor)).first() # finds users formatted like https://kbin.social/u/tables
user = User.query.filter(func.lower(User.ap_profile_id) == func.lower(actor)).first() # finds users formatted like https://kbin.social/u/tables
if (user and user.banned) or (user and user.deleted) :
return None
if user is None:
user = Community.query.filter(Community.ap_profile_id.ilike(actor)).first()
user = Community.query.filter(func.lower(Community.ap_profile_id) == func.lower(actor)).first()
if user is not None:
if not user.is_local() and user.ap_fetched_at < utcnow() - timedelta(days=7):

View file

@ -3,6 +3,7 @@ from wtforms import StringField, PasswordField, SubmitField, HiddenField, Boolea
from wtforms.validators import ValidationError, DataRequired, Email, EqualTo, Length
from flask_babel import _, lazy_gettext as _l
from app.models import User, Community
from sqlalchemy import func
class LoginForm(FlaskForm):
@ -26,18 +27,18 @@ class RegistrationForm(FlaskForm):
submit = SubmitField(_l('Register'))
def validate_real_email(self, email):
user = User.query.filter(User.email.ilike(email.data.strip())).first()
user = User.query.filter(func.lower(User.email) == func.lower(email.data.strip())).first()
if user is not None:
raise ValidationError(_l('An account with this email address already exists.'))
def validate_user_name(self, user_name):
user = User.query.filter(User.user_name.ilike(user_name.data.strip())).filter_by(ap_id=None).first()
user = User.query.filter(func.lower(User.user_name) == func.lower(user_name.data.strip())).filter_by(ap_id=None).first()
if user is not None:
if user.deleted:
raise ValidationError(_l('This username was used in the past and cannot be reused.'))
else:
raise ValidationError(_l('An account with this user name already exists.'))
community = Community.query.filter(Community.name.ilike(user_name.data.strip())).first()
community = Community.query.filter(func.lower(Community.name) == func.lower(user_name.data.strip())).first()
if community is not None:
raise ValidationError(_l('A community with this name exists so it cannot be used for a user.'))

View file

@ -16,7 +16,7 @@ from app.models import Community, File, BannedInstances, PostReply, PostVote, Po
Instance, Notification, User
from app.utils import get_request, gibberish, markdown_to_html, domain_from_url, allowlist_html, \
html_to_markdown, is_image_url, ensure_directory_exists, inbox_domain, post_ranking, shorten_string, parse_page
from sqlalchemy import desc, text
from sqlalchemy import func
import os
@ -116,7 +116,7 @@ def retrieve_mods_and_backfill(community_id: int):
def community_url_exists(url) -> bool:
community = Community.query.filter(Community.ap_profile_id.ilike(url)).first()
community = Community.query.filter(func.lower(Community.ap_profile_id) == func.lower(url)).first()
return community is not None
@ -125,7 +125,7 @@ def actor_to_community(actor) -> Community:
if '@' in actor:
community = Community.query.filter_by(banned=False, ap_id=actor).first()
else:
community = Community.query.filter(Community.name.ilike(actor)).filter_by(banned=False, ap_id=None).first()
community = Community.query.filter(func.lower(Community.name) == func.lower(actor)).filter_by(banned=False, ap_id=None).first()
return community