|
7 | 7 | import structlog |
8 | 8 | from sqlalchemy import ColumnElement, and_, distinct, func, or_, select, text |
9 | 9 | from sqlalchemy.orm import Session |
| 10 | +from sqlalchemy.sql.operators import ilike_op |
10 | 11 | from src.core.media_types import FILETYPE_EQUIVALENTS, MediaCategories |
11 | 12 | from src.core.query_lang import BaseVisitor |
12 | 13 | from src.core.query_lang.ast import ANDList, Constraint, ConstraintType, Not, ORList, Property |
13 | 14 |
|
14 | 15 | from .joins import TagEntry |
15 | 16 | from .models import Entry, Tag, TagAlias |
16 | 17 |
|
17 | | -# workaround to have autocompletion in the Editor |
| 18 | +# Only import for type checking/autocompletion, will not be imported at runtime. |
18 | 19 | if TYPE_CHECKING: |
19 | 20 | from .library import Library |
20 | 21 | else: |
@@ -97,7 +98,26 @@ def visit_constraint(self, node: Constraint) -> ColumnElement[bool]: |
97 | 98 | elif node.type == ConstraintType.TagID: |
98 | 99 | return self.__entry_matches_tag_ids([int(node.value)]) |
99 | 100 | elif node.type == ConstraintType.Path: |
100 | | - return Entry.path.op("GLOB")(node.value) |
| 101 | + smartcase = False |
| 102 | + glob = False |
| 103 | + |
| 104 | + if node.value == node.value.lower(): |
| 105 | + smartcase = True |
| 106 | + if "*" in node.value: |
| 107 | + glob = True |
| 108 | + |
| 109 | + if smartcase and glob: |
| 110 | + logger.info("ConstraintType.Path", smartcase=True, glob=True) |
| 111 | + return Entry.path.op("GLOB")(ilike_op(Entry.path, f"%{node.value}%")) |
| 112 | + elif smartcase: |
| 113 | + logger.info("ConstraintType.Path", smartcase=True, glob=False) |
| 114 | + return ilike_op(Entry.path, f"%{node.value}%") |
| 115 | + elif glob: |
| 116 | + logger.info("ConstraintType.Path", smartcase=False, glob=True) |
| 117 | + return Entry.path.op("GLOB")(node.value) |
| 118 | + else: |
| 119 | + logger.info("ConstraintType.Path", smartcase=False, glob=False) |
| 120 | + return Entry.path.regexp_match(rf"\b{node.value}\b") |
101 | 121 | elif node.type == ConstraintType.MediaType: |
102 | 122 | extensions: set[str] = set[str]() |
103 | 123 | for media_cat in MediaCategories.ALL_CATEGORIES: |
|
0 commit comments