Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: url query #52

Merged
merged 4 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions api/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ func (s *HttpServer) store() gin.HandlerFunc {
c.JSON(400, gin.H{"error": err.Error()})
return
}
if err := body.Valid(); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
body.Namespace = namespace
body.EntryId = entryId
// store the document
Expand Down Expand Up @@ -79,6 +83,10 @@ func (s *HttpServer) get() gin.HandlerFunc {
c.String(500, fmt.Sprintf("get document error: %s", err))
return
}
if document == nil {
c.String(404, fmt.Sprintf("document not found: %s", entryId))
return
}
docWithAttr := &DocumentWithAttr{
Document: document,
}
Expand All @@ -102,7 +110,7 @@ func (s *HttpServer) get() gin.HandlerFunc {
}
}

c.JSON(200, attrs)
c.JSON(200, docWithAttr)
}
}

Expand Down Expand Up @@ -170,8 +178,8 @@ func (s *HttpServer) filter() gin.HandlerFunc {
if fuzzyName != "" {
docQuery.FuzzyName = &fuzzyName
}
if c.Query("unread") != "" {
docQuery.UnRead = utils.ToPtr(c.Query("unread") == "true")
if c.Query("unRead") != "" {
docQuery.UnRead = utils.ToPtr(c.Query("unRead") == "true")
}
if c.Query("mark") != "" {
docQuery.Mark = utils.ToPtr(c.Query("mark") == "true")
Expand All @@ -191,10 +199,10 @@ func (s *HttpServer) filter() gin.HandlerFunc {
c.String(500, fmt.Sprintf("list document attrs error: %s", err))
return
}
attrsMap := map[string][]doc.DocumentAttr{}
attrsMap := map[string][]*doc.DocumentAttr{}
for _, attr := range allAttrs {
if attrsMap[attr.EntryId] == nil {
attrsMap[attr.EntryId] = []doc.DocumentAttr{}
attrsMap[attr.EntryId] = []*doc.DocumentAttr{}
}
attrsMap[attr.EntryId] = append(attrsMap[attr.EntryId], attr)
}
Expand Down Expand Up @@ -226,21 +234,21 @@ func (s *HttpServer) filter() gin.HandlerFunc {
func (s *HttpServer) delete() gin.HandlerFunc {
return func(c *gin.Context) {
namespace := c.Param("namespace")
queries := []doc.AttrQuery{}
queries := []*doc.AttrQuery{}
entryId := c.Param("entryId")
queries = append(queries,
doc.AttrQuery{
&doc.AttrQuery{
Attr: "entryId",
Option: "=",
Value: entryId,
},
doc.AttrQuery{
&doc.AttrQuery{
Attr: "namespace",
Option: "=",
Value: namespace,
},
)
if err := s.chain.DeleteByFilter(c, queries); err != nil {
if err := s.chain.DeleteByFilter(c, doc.DocumentAttrQuery{AttrQueries: queries}); err != nil {
c.String(500, fmt.Sprintf("delete document error: %s", err))
return
}
Expand Down
37 changes: 25 additions & 12 deletions api/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package api

import (
"fmt"

"github.com/google/uuid"

"github.com/basenana/friday/pkg/models/doc"
Expand All @@ -38,6 +40,7 @@ func (r *DocRequest) ToDocument() *doc.Document {
Id: uuid.New().String(),
EntryId: r.EntryId,
Name: r.Name,
Kind: "document",
Namespace: r.Namespace,
Source: r.Source,
WebUrl: r.WebUrl,
Expand All @@ -47,6 +50,16 @@ func (r *DocRequest) ToDocument() *doc.Document {
}
}

func (r *DocRequest) Valid() error {
if r.EntryId == "" || r.EntryId == "0" {
return fmt.Errorf("entryId is required")
}
if r.Namespace == "" {
return fmt.Errorf("namespace is required")
}
return nil
}

type DocAttrRequest struct {
Namespace string `json:"namespace"`
EntryId string `json:"entryId,omitempty"`
Expand Down Expand Up @@ -121,55 +134,55 @@ func (q *DocQuery) ToQuery() *doc.DocumentQuery {
Asc: !q.Desc,
}},
}
attrQueries := []doc.AttrQuery{{
attrQueries := []*doc.AttrQuery{{
Attr: "namespace",
Option: "=",
Value: q.Namespace,
}}
if q.Source != "" {
attrQueries = append(attrQueries, doc.AttrQuery{
attrQueries = append(attrQueries, &doc.AttrQuery{
Attr: "source",
Option: "=",
Value: q.Source,
})
}
if q.WebUrl != "" {
attrQueries = append(attrQueries, doc.AttrQuery{
attrQueries = append(attrQueries, &doc.AttrQuery{
Attr: "webUrl",
Option: "=",
Value: q.WebUrl,
})
}
if q.CreatedAtStart != nil {
attrQueries = append(attrQueries, doc.AttrQuery{
attrQueries = append(attrQueries, &doc.AttrQuery{
Attr: "createdAt",
Option: ">=",
Value: *q.CreatedAtStart,
})
}
if q.ChangedAtStart != nil {
attrQueries = append(attrQueries, doc.AttrQuery{
attrQueries = append(attrQueries, &doc.AttrQuery{
Attr: "updatedAt",
Option: ">=",
Value: *q.ChangedAtStart,
})
}
if q.CreatedAtEnd != nil {
attrQueries = append(attrQueries, doc.AttrQuery{
attrQueries = append(attrQueries, &doc.AttrQuery{
Attr: "createdAt",
Option: "<=",
Value: *q.CreatedAtEnd,
})
}
if q.ChangedAtEnd != nil {
attrQueries = append(attrQueries, doc.AttrQuery{
attrQueries = append(attrQueries, &doc.AttrQuery{
Attr: "updatedAt",
Option: "<=",
Value: *q.ChangedAtEnd,
})
}
if q.FuzzyName != nil {
attrQueries = append(attrQueries, doc.AttrQuery{
attrQueries = append(attrQueries, &doc.AttrQuery{
Attr: "name",
Option: "CONTAINS",
Value: *q.FuzzyName,
Expand All @@ -184,7 +197,7 @@ func (q *DocQuery) GetAttrQueries() []*doc.DocumentAttrQuery {
attrQueries := []*doc.DocumentAttrQuery{}
if q.UnRead != nil {
attrQueries = append(attrQueries, &doc.DocumentAttrQuery{
AttrQueries: []doc.AttrQuery{
AttrQueries: []*doc.AttrQuery{
{
Attr: "namespace",
Option: "=",
Expand All @@ -205,7 +218,7 @@ func (q *DocQuery) GetAttrQueries() []*doc.DocumentAttrQuery {
}
if q.Mark != nil {
attrQueries = append(attrQueries, &doc.DocumentAttrQuery{
AttrQueries: []doc.AttrQuery{
AttrQueries: []*doc.AttrQuery{
{
Attr: "namespace",
Option: "=",
Expand All @@ -226,7 +239,7 @@ func (q *DocQuery) GetAttrQueries() []*doc.DocumentAttrQuery {
}
if q.ParentID != "" {
attrQueries = append(attrQueries, &doc.DocumentAttrQuery{
AttrQueries: []doc.AttrQuery{
AttrQueries: []*doc.AttrQuery{
{
Attr: "namespace",
Option: "=",
Expand All @@ -249,7 +262,7 @@ func (q *DocQuery) GetAttrQueries() []*doc.DocumentAttrQuery {
}

type DocumentWithAttr struct {
doc.Document
*doc.Document

ParentID string `json:"parentId,omitempty"`
UnRead *bool `json:"unRead,omitempty"`
Expand Down
56 changes: 56 additions & 0 deletions pkg/models/doc/attr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
Copyright 2024 Friday Author.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package doc

import "fmt"

type DocumentAttr struct {
Id string `json:"id"`
Kind string `json:"kind"`
Namespace string `json:"namespace"`
EntryId string `json:"entryId"`
Key string `json:"key"`
Value interface{} `json:"value"`
}

var _ DocPtrInterface = &DocumentAttr{}

func (d *DocumentAttr) ID() string {
return d.Id
}

func (d *DocumentAttr) EntryID() string {
return d.EntryId
}

func (d *DocumentAttr) Type() string {
return "attr"
}

func (d *DocumentAttr) String() string {
return fmt.Sprintf("EntryId(%s) %s: %v", d.EntryId, d.Key, d.Value)
}

type DocumentAttrList []*DocumentAttr

func (d DocumentAttrList) String() string {
result := ""
for _, attr := range d {
result += fmt.Sprintf("EntryId(%s) %s: %v\n", attr.EntryId, attr.Key, attr.Value)
}
return result
}
102 changes: 9 additions & 93 deletions pkg/models/doc/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@
package doc

import (
"encoding/json"
"fmt"

"github.com/meilisearch/meilisearch-go"
)

var (
Expand Down Expand Up @@ -65,99 +62,18 @@ func (d *Document) Type() string {
return "document"
}

type DocumentAttr struct {
Id string `json:"id"`
Kind string `json:"kind"`
Namespace string `json:"namespace"`
EntryId string `json:"entryId"`
Key string `json:"key"`
Value interface{} `json:"value"`
}

func (d *DocumentAttr) ID() string {
return d.Id
}

func (d *DocumentAttr) EntryID() string {
return d.EntryId
}

func (d *DocumentAttr) Type() string {
return "attr"
}

var _ DocPtrInterface = &Document{}
var _ DocPtrInterface = &DocumentAttr{}

type DocumentQuery struct {
AttrQueries []AttrQuery

Search string
HitsPerPage int64
Page int64
Offset int64
Limit int64
Sort []Sort
func (d *Document) String() string {
return fmt.Sprintf("EntryId(%s) %s", d.EntryId, d.Name)
}

type Sort struct {
Attr string
Asc bool
}
type DocumentList []*Document

func (s *Sort) String() string {
if s.Asc {
return fmt.Sprintf("%s:asc", s.Attr)
func (d DocumentList) String() string {
result := ""
for _, doc := range d {
result += fmt.Sprintf("EntryId(%s) %s\n", doc.EntryId, doc.Name)
}
return fmt.Sprintf("%s:desc", s.Attr)
return result
}

type DocumentAttrQuery struct {
AttrQueries []AttrQuery
}

type AttrQuery struct {
Attr string
Option string
Value interface{}
}

func (aq *AttrQuery) ToFilter() interface{} {
vs, _ := json.Marshal(aq.Value)
return fmt.Sprintf("%s %s %s", aq.Attr, aq.Option, vs)
}

func (q *DocumentQuery) ToRequest() *meilisearch.SearchRequest {
// build filter
filter := []interface{}{}
for _, aq := range q.AttrQueries {
filter = append(filter, aq.ToFilter())
}
sorts := []string{}
for _, s := range q.Sort {
sorts = append(sorts, s.String())
}

return &meilisearch.SearchRequest{
Offset: q.Offset,
Limit: q.Limit,
Sort: sorts,
HitsPerPage: q.HitsPerPage,
Page: q.Page,
Query: q.Search,
Filter: filter,
}
}

func (q *DocumentAttrQuery) ToRequest() *meilisearch.SearchRequest {
filter := []interface{}{}
for _, aq := range q.AttrQueries {
filter = append(filter, aq.ToFilter())
}
return &meilisearch.SearchRequest{
Filter: filter,
Limit: 10000,
HitsPerPage: 10000,
Query: "",
}
}
var _ DocPtrInterface = &Document{}
Loading
Loading