elmeg-demo/backend/routers/search.py

93 lines
2.4 KiB
Python

from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlmodel import Session, select, col
from sqlalchemy.orm import selectinload
from database import get_session
from models import Show, Song, Venue, Tour, Group, Performance, PerformanceNickname, Comment, Review
from schemas import ShowRead, SongRead, VenueRead, TourRead, GroupRead
router = APIRouter(prefix="/search", tags=["search"])
@router.get("/")
def global_search(
q: str,
session: Session = Depends(get_session),
limit: int = 5
):
if len(q) < 2:
return {}
q_str = f"%{q}%"
# Search Songs
songs = session.exec(
select(Song)
.where(col(Song.title).ilike(q_str))
.limit(limit)
).all()
# Search Venues
venues = session.exec(
select(Venue)
.where(col(Venue.name).ilike(q_str))
.limit(limit)
).all()
# Search Tours
tours = session.exec(
select(Tour)
.where(col(Tour.name).ilike(q_str))
.limit(limit)
).all()
# Search Groups
groups = session.exec(
select(Group)
.where(col(Group.name).ilike(q_str))
.limit(limit)
).all()
# Search Nicknames
nicknames = session.exec(
select(PerformanceNickname)
.options(selectinload(PerformanceNickname.performance).selectinload(Performance.song))
.where(col(PerformanceNickname.nickname).ilike(q_str))
.where(PerformanceNickname.status == "approved")
.limit(limit)
).all()
# Search Performances by notes
performances = session.exec(
select(Performance)
.options(selectinload(Performance.song), selectinload(Performance.show))
.where(col(Performance.notes).ilike(q_str))
.limit(limit)
).all()
# Search Reviews
reviews = session.exec(
select(Review)
.where(
(col(Review.blurb).ilike(q_str)) |
(col(Review.content).ilike(q_str))
)
.limit(limit)
).all()
# Search Comments
comments = session.exec(
select(Comment)
.where(col(Comment.content).ilike(q_str))
.limit(limit)
).all()
return {
"songs": songs,
"venues": venues,
"tours": tours,
"groups": groups,
"nicknames": nicknames,
"performances": performances,
"reviews": reviews,
"comments": comments
}