101 lines
2.5 KiB
Go
101 lines
2.5 KiB
Go
package graph
|
|
|
|
// This file will be automatically regenerated based on the schema, any resolver implementations
|
|
// will be copied through when generating and any unknown code will be moved to the end.
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
|
|
"git.sr.ht/~sircmpwn/searchhut/database"
|
|
"git.sr.ht/~sircmpwn/searchhut/graph/generated"
|
|
"git.sr.ht/~sircmpwn/searchhut/graph/model"
|
|
)
|
|
|
|
// Domain is the resolver for the domain field.
|
|
func (r *pageResolver) Domain(ctx context.Context, obj *model.Page) (*model.Domain, error) {
|
|
panic(fmt.Errorf("not implemented"))
|
|
}
|
|
|
|
// Search is the resolver for the search field.
|
|
func (r *queryResolver) Search(ctx context.Context, query string) ([]*model.Result, error) {
|
|
var results []*model.Result
|
|
|
|
if err := database.WithTx(ctx, &sql.TxOptions{
|
|
Isolation: 0,
|
|
ReadOnly: true,
|
|
}, func(tx *sql.Tx) error {
|
|
rows, err := tx.QueryContext(ctx, `
|
|
SELECT
|
|
id,
|
|
domain_id,
|
|
url,
|
|
last_index_date,
|
|
title,
|
|
language,
|
|
description,
|
|
author,
|
|
excerpt,
|
|
ts_rank_cd(fts_vector, websearch_to_tsquery('english', $1), 32) AS rank
|
|
FROM page
|
|
WHERE websearch_to_tsquery('english', $1) @@ fts_vector
|
|
ORDER BY rank DESC
|
|
LIMIT 10;
|
|
`, query)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for rows.Next() {
|
|
var (
|
|
rank float32
|
|
page model.Page
|
|
)
|
|
if err := rows.Scan(&page.ID, &page.DomainID, &page.URL,
|
|
&page.LastIndexed, &page.Title, &page.Language,
|
|
&page.Description, &page.Author, &page.Excerpt,
|
|
&rank); err != nil {
|
|
return err
|
|
}
|
|
results = append(results, &model.Result{
|
|
Page: &page,
|
|
Context: nil, // TODO
|
|
})
|
|
}
|
|
|
|
return nil
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return results, nil
|
|
}
|
|
|
|
// Stats is the resolver for the stats field.
|
|
func (r *queryResolver) Stats(ctx context.Context) (*model.Stats, error) {
|
|
var stats model.Stats
|
|
if err := database.WithTx(ctx, &sql.TxOptions{
|
|
ReadOnly: true,
|
|
Isolation: 0,
|
|
}, func(tx *sql.Tx) error {
|
|
row := tx.QueryRowContext(ctx, `
|
|
SELECT
|
|
(SELECT count(*) FROM page),
|
|
(SELECT count(*) FROM domain),
|
|
(SELECT pg_database_size(current_database()));`)
|
|
return row.Scan(&stats.Npages, &stats.Ndomains, &stats.Indexbytes)
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
return &stats, nil
|
|
}
|
|
|
|
// Page returns generated.PageResolver implementation.
|
|
func (r *Resolver) Page() generated.PageResolver { return &pageResolver{r} }
|
|
|
|
// Query returns generated.QueryResolver implementation.
|
|
func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
|
|
|
|
type pageResolver struct{ *Resolver }
|
|
type queryResolver struct{ *Resolver }
|