mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-11-26 03:21:05 +00:00
Define author_search_vector_trigger
via Author.Meta.triggers
Previously, triggers lived only in a particular migration file. With this change, code for the triggers resides in the model, and their lifecycle is managed through normal Django migrations.
This commit is contained in:
parent
44ef928c3c
commit
416a6caf2d
5 changed files with 103 additions and 0 deletions
|
@ -0,0 +1,50 @@
|
|||
# Generated by Django 3.2.20 on 2023-11-25 00:47
|
||||
|
||||
from importlib import import_module
|
||||
import re
|
||||
|
||||
from django.db import migrations
|
||||
import pgtrigger.compiler
|
||||
import pgtrigger.migrations
|
||||
|
||||
trigger_migration = import_module("bookwyrm.migrations.0077_auto_20210623_2155")
|
||||
|
||||
# it's _very_ convenient for development that this migration be reversible
|
||||
search_vector_trigger = trigger_migration.Migration.operations[4]
|
||||
author_search_vector_trigger = trigger_migration.Migration.operations[5]
|
||||
|
||||
|
||||
assert re.search(r"\bCREATE TRIGGER search_vector_trigger\b", search_vector_trigger.sql)
|
||||
assert re.search(
|
||||
r"\bCREATE TRIGGER author_search_vector_trigger\b",
|
||||
author_search_vector_trigger.sql,
|
||||
)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("bookwyrm", "0190_book_search_updates"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
pgtrigger.migrations.AddTrigger(
|
||||
model_name="author",
|
||||
trigger=pgtrigger.compiler.Trigger(
|
||||
name="reset_search_vector_on_author_edit",
|
||||
sql=pgtrigger.compiler.UpsertTriggerSql(
|
||||
func="WITH book AS (SELECT bookwyrm_book.id AS row_id FROM bookwyrm_author LEFT OUTER JOIN bookwyrm_book_authors ON bookwyrm_book_authors.id = new.id LEFT OUTER JOIN bookwyrm_book ON bookwyrm_book.id = bookwyrm_book_authors.book_id) UPDATE bookwyrm_book SET search_vector = '' FROM book WHERE id = book.row_id;RETURN NEW;",
|
||||
hash="9c0a472e2bf60e63d593cce49f47972c7b227a00",
|
||||
operation='UPDATE OF "name"',
|
||||
pgid="pgtrigger_reset_search_vector_on_author_edit_a447c",
|
||||
table="bookwyrm_author",
|
||||
when="AFTER",
|
||||
),
|
||||
),
|
||||
),
|
||||
migrations.RunSQL(
|
||||
sql="""DROP TRIGGER IF EXISTS author_search_vector_trigger ON bookwyrm_author;
|
||||
DROP FUNCTION IF EXISTS author_trigger;
|
||||
""",
|
||||
reverse_sql=author_search_vector_trigger.sql,
|
||||
),
|
||||
]
|
|
@ -3,9 +3,11 @@ import re
|
|||
from typing import Tuple, Any
|
||||
|
||||
from django.db import models
|
||||
import pgtrigger
|
||||
|
||||
from bookwyrm import activitypub
|
||||
from bookwyrm.settings import DOMAIN
|
||||
from bookwyrm.utils.db import format_trigger
|
||||
|
||||
from .book import BookDataModel
|
||||
from . import fields
|
||||
|
@ -66,4 +68,31 @@ class Author(BookDataModel):
|
|||
"""editions and works both use "book" instead of model_name"""
|
||||
return f"https://{DOMAIN}/author/{self.id}"
|
||||
|
||||
class Meta:
|
||||
"""sets up indexes and triggers"""
|
||||
|
||||
triggers = [
|
||||
pgtrigger.Trigger(
|
||||
name="reset_search_vector_on_author_edit",
|
||||
when=pgtrigger.After,
|
||||
operation=pgtrigger.UpdateOf("name"),
|
||||
func=format_trigger(
|
||||
"""WITH book AS (
|
||||
SELECT bookwyrm_book.id AS row_id
|
||||
FROM bookwyrm_author
|
||||
LEFT OUTER JOIN bookwyrm_book_authors
|
||||
ON bookwyrm_book_authors.id = new.id
|
||||
LEFT OUTER JOIN bookwyrm_book
|
||||
ON bookwyrm_book.id = bookwyrm_book_authors.book_id
|
||||
)
|
||||
UPDATE bookwyrm_book
|
||||
SET search_vector = ''
|
||||
FROM book
|
||||
WHERE id = book.row_id;
|
||||
RETURN new;
|
||||
"""
|
||||
),
|
||||
)
|
||||
]
|
||||
|
||||
activity_serializer = activitypub.Author
|
||||
|
|
|
@ -104,6 +104,7 @@ INSTALLED_APPS = [
|
|||
"celery",
|
||||
"django_celery_beat",
|
||||
"imagekit",
|
||||
"pgtrigger",
|
||||
"storages",
|
||||
]
|
||||
|
||||
|
|
22
bookwyrm/utils/db.py
Normal file
22
bookwyrm/utils/db.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
""" Database utilities """
|
||||
|
||||
from typing import cast
|
||||
import sqlparse # type: ignore
|
||||
|
||||
|
||||
def format_trigger(sql: str) -> str:
|
||||
"""format SQL trigger before storing
|
||||
|
||||
we remove whitespace and use consistent casing so as to avoid migrations
|
||||
due to formatting changes.
|
||||
"""
|
||||
return cast(
|
||||
str,
|
||||
sqlparse.format(
|
||||
sql,
|
||||
strip_comments=True,
|
||||
strip_whitespace=True,
|
||||
keyword_case="upper",
|
||||
identifier_case="lower",
|
||||
),
|
||||
)
|
|
@ -7,6 +7,7 @@ django-celery-beat==2.4.0
|
|||
django-compressor==4.3.1
|
||||
django-imagekit==4.1.0
|
||||
django-model-utils==4.3.1
|
||||
django-pgtrigger==4.10.0
|
||||
django-sass-processor==1.2.2
|
||||
django-csp==3.7
|
||||
environs==9.5.0
|
||||
|
|
Loading…
Reference in a new issue