68 lines
1.6 KiB
Go
68 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
|
||
|
|
}
|