feat(storage,document,sqlite): implements order by and limit
This commit is contained in:
@ -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,
|
||||
|
Reference in New Issue
Block a user