Skip to content

Commit

Permalink
Implement full text search on all models
Browse files Browse the repository at this point in the history
  • Loading branch information
3j14 committed Jun 17, 2022
1 parent a85a0b0 commit 052a3c3
Show file tree
Hide file tree
Showing 21 changed files with 253 additions and 33 deletions.
32 changes: 32 additions & 0 deletions alembic/versions/b6f593818541_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""empty message
Revision ID: b6f593818541
Revises: c2d7aa36d0e7
Create Date: 2022-06-17 18:35:58.043728
"""
from alembic import op
import sqlalchemy as sa
from doku.models import TSVector


# revision identifiers, used by Alembic.

revision = 'b6f593818541'
down_revision = 'c2d7aa36d0e7'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('doku_document', sa.Column('__ts_vector__', TSVector(), sa.Computed("to_tsvector('english', name)", persisted=True), nullable=True))
op.create_index('doku_document___ts_vector__', 'doku_document', ['__ts_vector__'], unique=False, postgresql_using='gin')
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index('doku_document___ts_vector__', table_name='doku_document', postgresql_using='gin')
op.drop_column('doku_document', '__ts_vector__')
# ### end Alembic commands ###
43 changes: 43 additions & 0 deletions alembic/versions/c7d3e7e86fe0_all_models_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""empty message
Revision ID: c7d3e7e86fe0
Revises: b6f593818541
Create Date: 2022-06-17 18:58:45.565407
"""
from alembic import op
import sqlalchemy as sa
from doku.models import TSVector


# revision identifiers, used by Alembic.
revision = 'c7d3e7e86fe0'
down_revision = 'b6f593818541'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('doku_resource', sa.Column('__ts_vector__', TSVector(), sa.Computed("to_tsvector('english', name)", persisted=True), nullable=True))
op.create_index('doku_resource___ts_vector__', 'doku_resource', ['__ts_vector__'], unique=False, postgresql_using='gin')
op.add_column('doku_snippet', sa.Column('__ts_vector__', TSVector(), sa.Computed("to_tsvector('english', name)", persisted=True), nullable=True))
op.create_index('doku_snippet___ts_vector__', 'doku_snippet', ['__ts_vector__'], unique=False, postgresql_using='gin')
op.add_column('doku_stylesheet', sa.Column('__ts_vector__', TSVector(), sa.Computed("to_tsvector('english', name)", persisted=True), nullable=True))
op.create_index('doku_stylesheet___ts_vector__', 'doku_stylesheet', ['__ts_vector__'], unique=False, postgresql_using='gin')
op.add_column('doku_template', sa.Column('__ts_vector__', TSVector(), sa.Computed("to_tsvector('english', name)", persisted=True), nullable=True))
op.create_index('doku_template___ts_vector__', 'doku_template', ['__ts_vector__'], unique=False, postgresql_using='gin')
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index('doku_template___ts_vector__', table_name='doku_template', postgresql_using='gin')
op.drop_column('doku_template', '__ts_vector__')
op.drop_index('doku_stylesheet___ts_vector__', table_name='doku_stylesheet', postgresql_using='gin')
op.drop_column('doku_stylesheet', '__ts_vector__')
op.drop_index('doku_snippet___ts_vector__', table_name='doku_snippet', postgresql_using='gin')
op.drop_column('doku_snippet', '__ts_vector__')
op.drop_index('doku_resource___ts_vector__', table_name='doku_resource', postgresql_using='gin')
op.drop_column('doku_resource', '__ts_vector__')
# ### end Alembic commands ###
2 changes: 1 addition & 1 deletion doku/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "0.5.0"
__version__ = "0.5.1"
__author__ = "Jonas Drotleff <j.drotleff@desk-lab.de>"
__all__ = ["create_app", "cli"]

Expand Down
16 changes: 11 additions & 5 deletions doku/blueprints/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from flask import Blueprint, render_template
from flask import Blueprint, render_template, request

from doku.models import db
from doku.models.document import Document
Expand All @@ -15,9 +15,15 @@ def index():
ordering, order, direction = get_ordering(
Document, default_order="last_updated", default_dir="desc"
)
documents = (
db.session.query(Document).order_by(ordering).paginate(page=page, per_page=10)
)
query: str = request.args.get("query", "", type=str)
documents = db.session.query(Document)
if query != "":
documents = documents.filter(Document.__ts_vector__.match(query))
documents = documents.order_by(ordering).paginate(page=page, per_page=10)
return render_template(
"sites/index.html", documents=documents, order=order, direction=direction
"sites/index.html",
documents=documents,
order=order,
direction=direction,
query=query,
)
7 changes: 6 additions & 1 deletion doku/blueprints/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,18 @@ def index():
db.session.add(resource)
db.session.commit()
page = get_pagination_page()
resources = db.session.query(Resource).paginate(page=page, per_page=10)
query: str = request.args.get("query", "", type=str)
resources = db.session.query(Resource)
if query != "":
resources = resources.filter(Resource.__ts_vector__.match(query))
resources = resources.paginate(page=page, per_page=10)

resource_schemas = ResourceSchema(session=db.session, many=True)
return render_template(
"sites/resources.html",
resources_json=resource_schemas.dumps(resources.items),
resources=resources,
query=query,
)


Expand Down
12 changes: 10 additions & 2 deletions doku/blueprints/snippet.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,16 @@
@login_required
def index():
page = get_pagination_page()
snippets = db.session.query(Snippet).paginate(page=page, per_page=10)
return render_template("sites/snippets.html", snippets=snippets)
query: str = request.args.get("query", "", type=str)
snippets = db.session.query(Snippet)
if query != "":
snippets = snippets.filter(Snippet.__ts_vector__.match(query))
snippets = snippets.paginate(page=page, per_page=10)
return render_template(
"sites/snippets.html",
snippets=snippets,
query=query,
)


@bp.route("/<int:snippet_id>", methods=["GET", "POST"])
Expand Down
8 changes: 6 additions & 2 deletions doku/blueprints/stylesheets.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,17 @@ def index():
db.session.commit()

page = get_pagination_page()
stylesheets = db.session.query(Stylesheet).paginate(page=page, per_page=10)
query: str = request.args.get("query", "", type=str)
stylesheets = db.session.query(Stylesheet)
if query != "":
stylesheets = stylesheets.filter(Stylesheet.__ts_vector__.match(query))
stylesheets = stylesheets.paginate(page=page, per_page=10)

stylesheet_schemas = StylesheetSchema(
session=db.session, many=True, include=("source",)
)
return render_template(
"sites/stylesheets.html",
stylesheets_json=stylesheet_schemas.dumps(stylesheets.items),
stylesheets=stylesheets,
stylesheets=stylesheets, query=query
)
16 changes: 7 additions & 9 deletions doku/blueprints/template.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from flask import Blueprint, render_template
from flask import Blueprint, render_template, request

from doku import db
from doku.models.schemas import TemplateSchema, StylesheetSchema
Expand All @@ -13,19 +13,17 @@
@login_required
def index_all():
page = get_pagination_page()
ordering, order, direction = get_ordering(
Template, default_order="name", default_dir="asc"
)
templates = (
db.session.query(Template).order_by(ordering).paginate(page=page, per_page=10)
)
query: str = request.args.get("query", "", type=str)
templates = db.session.query(Template)
if query != "":
templates = templates.filter(Template.__ts_vector__.match(query))
templates = templates.paginate(page=page, per_page=10)
template_schema = TemplateSchema(session=db.session, many=True)
return render_template(
"sites/templates.html",
templates_json=template_schema.dumps(templates.items),
templates=templates,
order=order,
direction=direction,
query=query,
)


Expand Down
6 changes: 6 additions & 0 deletions doku/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@
from flask_babel import format_timedelta, format_datetime
from flask_sqlalchemy import SQLAlchemy
from marshmallow_sqlalchemy import auto_field
from sqlalchemy import TypeDecorator
from sqlalchemy.dialects.postgresql import TSVECTOR

db = SQLAlchemy(session_options={"autoflush": False})


class TSVector(TypeDecorator):
impl = TSVECTOR


class DateMixin:
created_on = db.Column(db.DateTime(timezone=True), default=datetime.now)
last_updated = db.Column(
Expand Down
15 changes: 14 additions & 1 deletion doku/models/document.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from flask import session
from sqlalchemy import Index

from doku.models import db, DateMixin
from doku.models import db, DateMixin, TSVector


class Document(db.Model, DateMixin):
Expand Down Expand Up @@ -34,6 +35,18 @@ class Document(db.Model, DateMixin):
overlaps="variables, document",
)

__ts_vector__ = db.Column(
TSVector(),
db.Computed(
"to_tsvector('english', name)",
persisted=True
)
)

__table_args__ = (
Index('doku_document___ts_vector__', __ts_vector__, postgresql_using='gin'),
)

def __init__(self, *args, author_id=None, author=None, **kwargs):
if author_id is None and author is None:
author_id = session.get("id", None)
Expand Down
15 changes: 14 additions & 1 deletion doku/models/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
import string

from flask import url_for
from sqlalchemy import Index
from werkzeug.utils import secure_filename

from doku.models import db, DateMixin
from doku.models import db, DateMixin, TSVector


class Resource(db.Model, DateMixin):
Expand All @@ -16,6 +17,18 @@ class Resource(db.Model, DateMixin):
name = db.Column(db.String(255), unique=False, nullable=False)
filename = db.Column(db.String(255), unique=True, nullable=False)

__ts_vector__ = db.Column(
TSVector(),
db.Computed(
"to_tsvector('english', name)",
persisted=True
)
)

__table_args__ = (
Index('doku_resource___ts_vector__', __ts_vector__, postgresql_using='gin'),
)

@property
def url(self):
return url_for("resources.view", resource_id=self.id)
Expand Down
16 changes: 14 additions & 2 deletions doku/models/snippet.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from sqlalchemy import event
from sqlalchemy import event, Index

from doku.models import db, DateMixin
from doku.models import db, DateMixin, TSVector
from doku.utils.markdown import compile_content


Expand All @@ -23,6 +23,18 @@ class Snippet(db.Model, DateMixin):

used_by = db.relationship("Variable")

__ts_vector__ = db.Column(
TSVector(),
db.Computed(
"to_tsvector('english', name)",
persisted=True
)
)

__table_args__ = (
Index('doku_snippet___ts_vector__', __ts_vector__, postgresql_using='gin'),
)

def __str__(self):
return f"Snippet {self.name}"

Expand Down
27 changes: 26 additions & 1 deletion doku/models/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
from jinja2 import Environment, meta
from jinja2 import Template as Jinja2Template
from pygments.formatters.html import HtmlFormatter
from sqlalchemy import Index
from weasyprint import HTML, CSS

from doku.models import db, DateMixin
from doku.models import db, DateMixin, TSVector
from doku.utils.weasyfetch import url_fetcher

DEFAULT_TEMPLATE = """<!doctype html>
Expand Down Expand Up @@ -49,6 +50,18 @@ class Template(db.Model, DateMixin):
"Stylesheet", secondary=template_stylesheet_relation, back_populates="templates"
)

__ts_vector__ = db.Column(
TSVector(),
db.Computed(
"to_tsvector('english', name)",
persisted=True
)
)

__table_args__ = (
Index('doku_template___ts_vector__', __ts_vector__, postgresql_using='gin'),
)

def __str__(self):
return self.name

Expand Down Expand Up @@ -110,6 +123,18 @@ class Stylesheet(db.Model, DateMixin):

MAX_CONTENT_LENGTH = 125000

__ts_vector__ = db.Column(
TSVector(),
db.Computed(
"to_tsvector('english', name)",
persisted=True
)
)

__table_args__ = (
Index('doku_stylesheet___ts_vector__', __ts_vector__, postgresql_using='gin'),
)

def __str__(self):
return self.name

Expand Down
15 changes: 15 additions & 0 deletions doku/static/src/sites/templates.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
Create new template
</button>
</div>
<form action="" class="mb-2" method="get">
<input type="hidden" name="page" :value="formPage"/>
<div class="form-inline">
<input class="form-input input-sm" type="text" name="query" :value="formQuery" placeholder="Search">
</div>
<button class="btn btn-sm btn-primary" type="submit">
Search
</button>
</form>

<template-item
v-for="template in templates"
Expand Down Expand Up @@ -61,6 +70,12 @@ export default {
components: {
TemplateItem, Modal, PlusIcon
},
data() {
return {
formPage: window._formPage,
formQuery: window._formQuery,
};
},
computed: mapState({
templates: state => state.template.templates,
}),
Expand Down
Loading

0 comments on commit 052a3c3

Please sign in to comment.