writekit/internal/tenant/search.go
2026-01-09 00:16:46 +02:00

67 lines
1.6 KiB
Go

package tenant
import (
"context"
)
type SearchResult struct {
Slug string
Collection string
Title string
Snippet string
Type string
URL string
Date string
}
func (q *Queries) Search(ctx context.Context, query string, limit int) ([]SearchResult, error) {
if limit <= 0 {
limit = 20
}
rows, err := q.db.QueryContext(ctx,
`SELECT slug, collection_slug, title, snippet(search_index, 4, '<mark>', '</mark>', '...', 32), type, url, date
FROM search_index
WHERE search_index MATCH ?
ORDER BY rank
LIMIT ?`, query, limit)
if err != nil {
return nil, err
}
defer rows.Close()
var results []SearchResult
for rows.Next() {
var r SearchResult
if err := rows.Scan(&r.Slug, &r.Collection, &r.Title, &r.Snippet, &r.Type, &r.URL, &r.Date); err != nil {
return nil, err
}
results = append(results, r)
}
return results, rows.Err()
}
func (q *Queries) IndexPost(ctx context.Context, p *Post) error {
q.db.ExecContext(ctx, `DELETE FROM search_index WHERE slug = ? AND type = 'post'`, p.Slug)
if !p.IsPublished {
return nil
}
dateStr := ""
if p.PublishedAt != nil {
dateStr = p.PublishedAt.Format("2006-01-02")
}
_, err := q.db.ExecContext(ctx,
`INSERT INTO search_index (slug, collection_slug, title, description, content, type, url, date)
VALUES (?, ?, ?, ?, ?, 'post', ?, ?)`,
p.Slug, "", p.Title, p.Description, p.ContentMD,
"/posts/"+p.Slug, dateStr)
return err
}
func (q *Queries) RemoveFromIndex(ctx context.Context, slug, itemType string) error {
_, err := q.db.ExecContext(ctx, `DELETE FROM search_index WHERE slug = ? AND type = ?`, slug, itemType)
return err
}