130 lines
3.7 KiB
Python
130 lines
3.7 KiB
Python
import uuid
|
|
from typing import Any, Dict, List, Union
|
|
|
|
from sqlalchemy import or_
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.crud.base import CRUDBase
|
|
from app.models.note import Note
|
|
from app.models.note_tag import NoteTag
|
|
from app.schemas.note import NoteCreate, NoteUpdate
|
|
|
|
|
|
class CRUDNote(CRUDBase[Note, NoteCreate, NoteUpdate]):
|
|
def get_multi_by_user(
|
|
self, db: Session, *, user_id: str, skip: int = 0, limit: int = 100, archived: bool = False
|
|
) -> List[Note]:
|
|
"""
|
|
Get multiple notes for a specific user.
|
|
"""
|
|
return (
|
|
db.query(self.model)
|
|
.filter(Note.user_id == user_id, Note.is_archived == archived)
|
|
.order_by(Note.is_pinned.desc(), Note.created_at.desc())
|
|
.offset(skip)
|
|
.limit(limit)
|
|
.all()
|
|
)
|
|
|
|
def create_with_user(
|
|
self, db: Session, *, obj_in: NoteCreate, user_id: str
|
|
) -> Note:
|
|
"""
|
|
Create a new note for a specific user.
|
|
"""
|
|
note_id = str(uuid.uuid4())
|
|
db_obj = Note(
|
|
id=note_id,
|
|
title=obj_in.title,
|
|
content=obj_in.content,
|
|
is_archived=obj_in.is_archived,
|
|
is_pinned=obj_in.is_pinned,
|
|
user_id=user_id,
|
|
)
|
|
db.add(db_obj)
|
|
db.commit()
|
|
db.refresh(db_obj)
|
|
|
|
# Add tags if provided
|
|
if obj_in.tag_ids:
|
|
for tag_id in obj_in.tag_ids:
|
|
note_tag = NoteTag(
|
|
id=str(uuid.uuid4()),
|
|
note_id=note_id,
|
|
tag_id=tag_id,
|
|
)
|
|
db.add(note_tag)
|
|
db.commit()
|
|
db.refresh(db_obj)
|
|
|
|
return db_obj
|
|
|
|
def update_note_tags(
|
|
self, db: Session, *, db_obj: Note, tag_ids: List[str]
|
|
) -> Note:
|
|
"""
|
|
Update the tags associated with a note.
|
|
"""
|
|
# Remove all existing tags
|
|
db.query(NoteTag).filter(NoteTag.note_id == db_obj.id).delete()
|
|
|
|
# Add new tags
|
|
for tag_id in tag_ids:
|
|
note_tag = NoteTag(
|
|
id=str(uuid.uuid4()),
|
|
note_id=db_obj.id,
|
|
tag_id=tag_id,
|
|
)
|
|
db.add(note_tag)
|
|
|
|
db.commit()
|
|
db.refresh(db_obj)
|
|
return db_obj
|
|
|
|
def update(
|
|
self, db: Session, *, db_obj: Note, obj_in: Union[NoteUpdate, Dict[str, Any]]
|
|
) -> Note:
|
|
"""
|
|
Update a note.
|
|
"""
|
|
if isinstance(obj_in, dict):
|
|
update_data = obj_in
|
|
tag_ids = update_data.pop("tag_ids", None)
|
|
else:
|
|
update_data = obj_in.dict(exclude_unset=True)
|
|
tag_ids = update_data.pop("tag_ids", None) if hasattr(obj_in, "tag_ids") else None
|
|
|
|
# Update the note
|
|
obj = super().update(db, db_obj=db_obj, obj_in=update_data)
|
|
|
|
# Update tags if provided
|
|
if tag_ids is not None:
|
|
self.update_note_tags(db, db_obj=obj, tag_ids=tag_ids)
|
|
db.refresh(obj)
|
|
|
|
return obj
|
|
|
|
def search_notes(
|
|
self, db: Session, *, user_id: str, query: str, skip: int = 0, limit: int = 100
|
|
) -> List[Note]:
|
|
"""
|
|
Search for notes by title or content.
|
|
"""
|
|
search_term = f"%{query}%"
|
|
return (
|
|
db.query(self.model)
|
|
.filter(
|
|
Note.user_id == user_id,
|
|
or_(
|
|
Note.title.ilike(search_term),
|
|
Note.content.ilike(search_term)
|
|
)
|
|
)
|
|
.order_by(Note.created_at.desc())
|
|
.offset(skip)
|
|
.limit(limit)
|
|
.all()
|
|
)
|
|
|
|
|
|
note = CRUDNote(Note) |