Skip to content

Commit dd5c3ba

Browse files
committed
Updated with query handler
1 parent 9692bf9 commit dd5c3ba

File tree

5 files changed

+128
-3
lines changed

5 files changed

+128
-3
lines changed

cmd/indexer/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func main() {
8989
defer pool.Close()
9090

9191
// Create store
92-
store := indexer.NewStore(pool, "main", idx.Queue(), *flagWorkers)
92+
store := indexer.NewStore(pool, "main", idx.Queue(), nil, *flagWorkers)
9393
if store == nil {
9494
fmt.Fprintln(os.Stderr, "failed to create store")
9595
os.Exit(-1)

pkg/indexer/schema.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,16 @@ func Delete(schema string, evt *QueueEvent) (SQStatement, []interface{}) {
154154
return N(filesTableName).WithSchema(schema).Delete(Q("name=?"), Q("path=?")),
155155
[]interface{}{evt.Name, evt.Path}
156156
}
157+
158+
func Query(schema string) SQSelect {
159+
return S(N(searchTableName).WithSchema(schema)).
160+
To(
161+
N("rowid"),
162+
N("rank"),
163+
N("name"),
164+
N("parent"),
165+
N("filename"),
166+
).
167+
Where(Q(searchTableName, " MATCH ", P)).
168+
Order(N("rank"))
169+
}

plugin/indexer/handlers.go

Lines changed: 105 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package main
22

33
import (
44
"context"
5+
"io"
56
"net/http"
67
"regexp"
8+
"strings"
79

810
// Packages
911
router "github.com/mutablelogic/go-server/pkg/httprouter"
@@ -12,6 +14,7 @@ import (
1214

1315
// Namespace imports
1416
. "github.com/mutablelogic/go-server"
17+
. "github.com/mutablelogic/go-sqlite"
1518
)
1619

1720
///////////////////////////////////////////////////////////////////////////////
@@ -30,18 +33,45 @@ type IndexResponse struct {
3033
Status string `json:"status,omitempty"`
3134
}
3235

36+
type QueryRequest struct {
37+
Query string `json:"q"`
38+
Offset uint `json:"offset"`
39+
Limit uint `json:"limit"`
40+
}
41+
42+
type QueryResponse struct {
43+
Query string `json:"q"`
44+
Offset uint `json:"offset,omitempty"`
45+
Limit uint `json:"limit,omitempty"`
46+
Results []ResultResponse `json:"results"`
47+
}
48+
49+
type ResultResponse struct {
50+
Id int64 `json:"id"`
51+
Offset int64 `json:"offset"`
52+
Rank float64 `json:"rank"`
53+
Index string `json:"index"`
54+
File FileResponse `json:"file"`
55+
}
56+
57+
type FileResponse struct {
58+
Parent string `json:"parent"`
59+
Filename string `json:"filename"`
60+
}
61+
3362
///////////////////////////////////////////////////////////////////////////////
3463
// ROUTES
3564

3665
var (
37-
reRoutePing = regexp.MustCompile(`^/?$`)
66+
reRoutePing = regexp.MustCompile(`^/?$`)
67+
reRouteQuery = regexp.MustCompile(`^/q/?$`)
3868
)
3969

4070
///////////////////////////////////////////////////////////////////////////////
4171
// CONSTANTS
4272

4373
const (
44-
maxResultLimit = 1000
74+
maxResultLimit = 100
4575
)
4676

4777
///////////////////////////////////////////////////////////////////////////////
@@ -53,6 +83,11 @@ func (p *plugin) AddHandlers(ctx context.Context, provider Provider) error {
5383
return err
5484
}
5585

86+
// Add handler for search
87+
if err := provider.AddHandlerFuncEx(ctx, reRouteQuery, p.ServeQuery); err != nil {
88+
return err
89+
}
90+
5691
// Return success
5792
return nil
5893
}
@@ -107,6 +142,74 @@ func (p *plugin) ServePing(w http.ResponseWriter, req *http.Request) {
107142
router.ServeJSON(w, response, http.StatusOK, 2)
108143
}
109144

145+
func (p *plugin) ServeQuery(w http.ResponseWriter, req *http.Request) {
146+
// Get a connection
147+
conn := p.pool.Get()
148+
if conn == nil {
149+
router.ServeError(w, http.StatusBadGateway, "No connection")
150+
return
151+
}
152+
defer p.pool.Put(conn)
153+
154+
// Decode the query
155+
var query QueryRequest
156+
if err := router.RequestQuery(req, &query); err != nil {
157+
router.ServeError(w, http.StatusBadRequest, err.Error())
158+
return
159+
}
160+
161+
// Check query, offset and limit
162+
query.Limit = uintMin(query.Limit, maxResultLimit)
163+
query.Query = strings.TrimSpace(query.Query)
164+
if query.Query == "" {
165+
router.ServeError(w, http.StatusBadRequest, "missing q parameter")
166+
return
167+
}
168+
169+
// Make a response
170+
response := QueryResponse{
171+
Query: query.Query,
172+
Offset: query.Offset,
173+
Limit: query.Limit,
174+
Results: make([]ResultResponse, 0, query.Limit),
175+
}
176+
177+
// Perform the query and collate the results
178+
if err := conn.Do(req.Context(), 0, func(txn SQTransaction) error {
179+
r, err := txn.Query(indexer.Query(p.store.Schema()).WithLimitOffset(query.Limit, query.Offset), query.Query)
180+
if err != nil {
181+
return err
182+
}
183+
n := int64(0)
184+
for {
185+
rows, err := r.Next()
186+
if err == io.EOF {
187+
return nil
188+
} else if err != nil {
189+
return err
190+
} else {
191+
n = n + 1
192+
}
193+
response.Results = append(response.Results, ResultResponse{
194+
Id: rows[0].(int64),
195+
Offset: n + int64(query.Offset) - 1,
196+
Rank: rows[1].(float64),
197+
Index: rows[2].(string),
198+
File: FileResponse{
199+
Parent: rows[3].(string),
200+
Filename: rows[4].(string),
201+
},
202+
})
203+
}
204+
}); err != nil {
205+
router.ServeError(w, http.StatusBadRequest, err.Error())
206+
return
207+
}
208+
209+
// Serve response
210+
router.ServeJSON(w, response, http.StatusOK, 2)
211+
}
212+
110213
///////////////////////////////////////////////////////////////////////////////
111214
// PRIVATE METHODS
112215

plugin/indexer/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ func (p *plugin) Run(ctx context.Context, provider Provider) error {
152152
}
153153

154154
// Run indexer processes
155+
// TODO: Report error when indexer can't be started
155156
for _, idx := range p.index {
156157
wg.Add(1)
157158
go func(idx *indexer.Indexer) {

plugin/indexer/util.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package main
2+
3+
func uintMin(a, b uint) uint {
4+
if a < b {
5+
return a
6+
}
7+
return b
8+
}

0 commit comments

Comments
 (0)