|
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