+1
-1
@@ -197,7 +197,7 @@ pre.raw-line { background: var(--bs-tertiary-bg); padding: .75rem; border-radius
|
||||
<input type="text" class="form-control" id="logSearchInput" placeholder="Search all log lines..." maxlength="200">
|
||||
<button class="btn btn-primary" id="logSearchBtn"><i class="bi bi-search me-1"></i>Search</button>
|
||||
</div>
|
||||
<small class="text-secondary mt-1 d-block">Search terms: <code>error 500</code>, <code>"disk full"</code>, <code>auth*</code>. Boolean operators like <code>NOT</code> not supported.</small>
|
||||
<small class="text-secondary mt-1 d-block">Use <code>*</code> as wildcard. <code>bla</code> matches "blabla". <code>*</code> shows all logs. Separate terms match all (AND).</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
|
||||
+25
-13
@@ -176,24 +176,15 @@ class Repository
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
if ($query === '*') {
|
||||
$stmt = $this->db->pdo()->prepare(
|
||||
"SELECT e.* FROM log_entries e
|
||||
JOIN log_entries_fts fts ON e.id = fts.rowid
|
||||
WHERE log_entries_fts MATCH ?
|
||||
ORDER BY rank
|
||||
LIMIT ? OFFSET ?"
|
||||
"SELECT * FROM log_entries ORDER BY created_at DESC LIMIT ? OFFSET ?"
|
||||
);
|
||||
$stmt->execute([$query, $limit, $offset]);
|
||||
$stmt->execute([$limit, $offset]);
|
||||
return $stmt->fetchAll();
|
||||
} catch (\PDOException $e) {
|
||||
return $this->searchLogEntriesLike($query, $limit, $offset);
|
||||
}
|
||||
}
|
||||
|
||||
private function searchLogEntriesLike(string $query, int $limit = 200, int $offset = 0): array
|
||||
{
|
||||
$like = '%' . str_replace(['%', '_'], ['\\%', '\\_'], $query) . '%';
|
||||
$like = $this->toLikePattern($query);
|
||||
$stmt = $this->db->pdo()->prepare(
|
||||
"SELECT e.* FROM log_entries e
|
||||
WHERE e.line LIKE ?
|
||||
@@ -204,6 +195,27 @@ class Repository
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
private function toLikePattern(string $query): string
|
||||
{
|
||||
$parts = preg_split('/\s+/', $query);
|
||||
$likeParts = [];
|
||||
foreach ($parts as $part) {
|
||||
$escaped = '';
|
||||
for ($i = 0; $i < strlen($part); $i++) {
|
||||
$ch = $part[$i];
|
||||
if ($ch === '*') {
|
||||
$escaped .= '%';
|
||||
} elseif ($ch === '%' || $ch === '_') {
|
||||
$escaped .= '\\' . $ch;
|
||||
} else {
|
||||
$escaped .= $ch;
|
||||
}
|
||||
}
|
||||
$likeParts[] = '%' . $escaped . '%';
|
||||
}
|
||||
return implode('%', $likeParts);
|
||||
}
|
||||
|
||||
// --- Config ---
|
||||
|
||||
public function getAllowedUserTokens(): array
|
||||
|
||||
Reference in New Issue
Block a user