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, '', '', '...', 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 }