From 70730a9a6b964636acd43366dcd3cd4c69e114db Mon Sep 17 00:00:00 2001 From: LordNoteworthy Date: Thu, 21 Dec 2023 18:39:23 +1100 Subject: [PATCH] allow fields choice in query files resource --- .env | 2 +- .vscode/launch.json | 6 +++++- internal/file/api.go | 17 ++++++++++++++++- internal/file/repository.go | 18 +++++++++++++++--- internal/file/service.go | 6 +++--- 5 files changed, 40 insertions(+), 9 deletions(-) diff --git a/.env b/.env index 63f7c8a..e6d1f1e 100644 --- a/.env +++ b/.env @@ -1,4 +1,4 @@ -export SAFERWALL_VER = 0.4.0 # Current Version +export SAFERWALL_VER = 0.5.0 # Current Version export DOCKER_HUB_USR = saferwall # Dockerhub username export DOCKER_HUB_IMG = webapis # Dockerhub image name export COUCHBASE_BUCKETS_LIST = sfw # Couchbase bucket names list diff --git a/.vscode/launch.json b/.vscode/launch.json index caecca5..a5325d9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,11 @@ "type": "go", "request": "launch", "mode": "debug", - "program": "${workspaceFolder}/cmd" + "program": "${workspaceFolder}/cmd", + "env": { + "SFW_WEBAPIS_DEPLOYMENT_KIND": "local" + }, + "dlvFlags": ["--check-go-version=false"], } ] } diff --git a/internal/file/api.go b/internal/file/api.go index 400d4a0..fce7090 100644 --- a/internal/file/api.go +++ b/internal/file/api.go @@ -267,12 +267,27 @@ func (r resource) list(c echo.Context) error { return errors.Forbidden("") } + // the `fields` query parameter is used to limit the fields + // to include in the response. + var fields []string + if fieldsParam := c.QueryParam("fields"); fieldsParam != "" { + fields = strings.Split(fieldsParam, ",") + } + + if len(fields) > 0 { + allowed := areFieldsAllowed(fields) + if !allowed { + return errors.BadRequest("field not allowed") + } + } + count, err := r.service.Count(ctx) if err != nil { return err } + pages := pagination.NewFromRequest(c.Request(), count) - files, err := r.service.Query(ctx, pages.Offset(), pages.Limit()) + files, err := r.service.Query(ctx, pages.Offset(), pages.Limit(), fields) if err != nil { return err } diff --git a/internal/file/repository.go b/internal/file/repository.go index c4ffa80..8b8b6e3 100644 --- a/internal/file/repository.go +++ b/internal/file/repository.go @@ -7,6 +7,7 @@ package file import ( "context" "encoding/json" + "fmt" "strings" dbcontext "github.com/saferwall/saferwall-api/internal/db" @@ -23,7 +24,7 @@ type Repository interface { // Exists return true when the doc exists in the DB. Exists(ctx context.Context, id string) (bool, error) // Query returns the list of files with the given offset and limit. - Query(ctx context.Context, offset, limit int) ([]entity.File, error) + Query(ctx context.Context, offset, limit int, fields []string) ([]entity.File, error) // Create saves a new file in the storage. Create(ctx context.Context, id string, file entity.File) error // Update updates the whole file with given ID in the storage. @@ -121,7 +122,7 @@ func (r repository) Count(ctx context.Context) (int, error) { // Query retrieves the file records with the specified offset and limit // from the database. -func (r repository) Query(ctx context.Context, offset, limit int) ( +func (r repository) Query(ctx context.Context, offset, limit int, fields []string) ( []entity.File, error) { var res interface{} @@ -129,8 +130,19 @@ func (r repository) Query(ctx context.Context, offset, limit int) ( params["docType"] = "file" params["offset"] = offset params["limit"] = limit - statement := r.db.N1QLQuery[dbcontext.GetAllDocType] + + if len(fields) > 0 { + statement = "SELECT " + for _, field := range fields { + statement += fmt.Sprintf("%s,", field) + } + statement = strings.TrimSuffix(statement, ",") + statement += fmt.Sprintf(" FROM `%s` WHERE type = $docType OFFSET $offset LIMIT $limit", + r.db.Bucket.Name()) + + } + err := r.db.Query(ctx, statement, params, &res) if err != nil { return []entity.File{}, err diff --git a/internal/file/service.go b/internal/file/service.go index 9fff4ea..8759a2a 100644 --- a/internal/file/service.go +++ b/internal/file/service.go @@ -43,7 +43,7 @@ type Service interface { Create(ctx context.Context, input CreateFileRequest) (File, error) Update(ctx context.Context, id string, input UpdateFileRequest) (File, error) Delete(ctx context.Context, id string) (File, error) - Query(ctx context.Context, offset, limit int) ([]File, error) + Query(ctx context.Context, offset, limit int, fields []string) ([]File, error) Patch(ctx context.Context, key, path string, val interface{}) error Summary(ctx context.Context, id string) (interface{}, error) Like(ctx context.Context, id string) error @@ -315,10 +315,10 @@ func (s service) Exists(ctx context.Context, id string) (bool, error) { } // Query returns the files with the specified offset and limit. -func (s service) Query(ctx context.Context, offset, limit int) ( +func (s service) Query(ctx context.Context, offset, limit int, fields []string) ( []File, error) { - items, err := s.repo.Query(ctx, offset, limit) + items, err := s.repo.Query(ctx, offset, limit, fields) if err != nil { return nil, err }