feat(storage,document,sqlite): implements order by and limit

This commit is contained in:
2023-03-01 12:12:11 +01:00
parent 4eb1f8fc90
commit 5ad4ab2e23
3 changed files with 269 additions and 10 deletions

View File

@ -4,6 +4,7 @@ import (
"context"
"database/sql"
"fmt"
"math"
"sync"
"time"
@ -90,6 +91,11 @@ func (s *DocumentStore) Get(ctx context.Context, collection string, id storage.D
// Query implements storage.DocumentStore
func (s *DocumentStore) Query(ctx context.Context, collection string, filter *filter.Filter, funcs ...storage.QueryOptionFunc) ([]storage.Document, error) {
opts := &storage.QueryOptions{}
for _, fn := range funcs {
fn(opts)
}
var documents []storage.Document
err := s.withTx(ctx, func(tx *sql.Tx) error {
@ -120,6 +126,24 @@ func (s *DocumentStore) Query(ctx context.Context, collection string, filter *fi
args = append([]interface{}{collection}, args...)
if opts.OrderBy != nil {
query, args = withOrderByClause(query, args, *opts.OrderBy, *opts.OrderDirection)
}
if opts.Offset != nil || opts.Limit != nil {
offset := 0
if opts.Offset != nil {
offset = *opts.Offset
}
limit := math.MaxInt
if opts.Limit != nil {
limit = *opts.Limit
}
query, args = withLimitOffsetClause(query, args, limit, offset)
}
logger.Debug(
ctx, "executing query",
logger.F("query", query),
@ -331,6 +355,41 @@ func (s *DocumentStore) ensureTables(ctx context.Context, db *sql.DB) error {
return nil
}
func withOrderByClause(query string, args []any, orderBy string, orderDirection storage.OrderDirection) (string, []any) {
direction := "ASC"
if orderDirection == storage.OrderDirectionDesc {
direction = "DESC"
}
var column string
switch orderBy {
case storage.DocumentAttrID:
column = "id"
case storage.DocumentAttrCreatedAt:
column = "created_at"
case storage.DocumentAttrUpdatedAt:
column = "updated_at"
default:
column = fmt.Sprintf("json_extract(data, '$.' || $%d)", len(args)+1)
args = append(args, orderBy)
}
query += fmt.Sprintf(`ORDER BY %s %s`, column, direction)
return query, args
}
func withLimitOffsetClause(query string, args []any, limit int, offset int) (string, []any) {
query += fmt.Sprintf(`LIMIT $%d OFFSET $%d`, len(args)+1, len(args)+2)
args = append(args, limit, offset)
return query, args
}
func NewDocumentStore(path string) *DocumentStore {
return &DocumentStore{
db: nil,