Added command history (#45)

* Added command line history to the command, query and filter prompts.
* Added query planning debugging to the log.
* Fixed bug in query expression which was not treating true and false as boolean literals.
* Fixed a bug in the query planning logic which was incorrectly determine that an expression of the form sort_key ^= "string", with no partition key, could be executed as a query instead of a scan.
This commit is contained in:
Leon Mika 2023-01-26 21:46:31 +11:00 committed by GitHub
parent 700a1a2253
commit 54a120342e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 335 additions and 34 deletions

View file

@ -0,0 +1,13 @@
package services
type HistoryProvider interface {
// Len returns the number of historical items
Len() int
// Item returns the historical item at index 'idx', where items are chronologically ordered such that the
// item at 0 is the oldest item.
Item(idx int) string
// PutItem adds an item to the history
PutItem(item string)
}

View file

@ -0,0 +1,8 @@
package inputhistory
import "context"
type HistoryItemStore interface {
Items(ctx context.Context, category string) ([]string, error)
PutItem(ctx context.Context, category string, item string) error
}

View file

@ -0,0 +1,49 @@
package inputhistory
import (
"context"
"github.com/lmika/audax/internal/dynamo-browse/services"
"log"
"strings"
)
func (svc *Service) Iter(ctx context.Context, category string) services.HistoryProvider {
items, err := svc.store.Items(ctx, category)
if err != nil {
log.Printf("warn: cannot get iter for '%v': %v", category, err)
return nil
}
return &Iter{svc, items, category}
}
func (svc *Service) PutItem(ctx context.Context, category string, value string) error {
return svc.store.PutItem(ctx, category, value)
}
type Iter struct {
svc *Service
items []string
category string
}
func (i *Iter) Len() int {
return len(i.items)
}
func (i *Iter) Item(idx int) string {
return i.items[idx]
}
func (i *Iter) PutItem(item string) {
if strings.TrimSpace(item) == "" {
return
}
if len(i.items) > 0 && i.items[len(i.items)-1] == item {
return
}
if err := i.svc.PutItem(context.Background(), i.category, item); err != nil {
log.Printf("warn: cannot put input history: category = %v, value = %v, err = %v", i.category, item, err)
}
}

View file

@ -0,0 +1,9 @@
package inputhistory
type Service struct {
store HistoryItemStore
}
func New(store HistoryItemStore) *Service {
return &Service{store: store}
}

View file

@ -59,15 +59,18 @@ func (s *Service) doScan(
runAsQuery = plan.CanQuery
filterExpr = &plan.Expression
log.Printf("Running query over '%v'", tableInfo.Name)
plan.Describe(log.Default())
} else {
log.Printf("Performing scan over '%v'", tableInfo.Name)
}
var results []models.Item
var lastEvalKey map[string]types.AttributeValue
if runAsQuery {
log.Printf("executing query")
results, lastEvalKey, err = s.provider.QueryItems(ctx, tableInfo.Name, filterExpr, exclusiveStartKey, limit)
} else {
log.Printf("executing scan")
results, lastEvalKey, err = s.provider.ScanItems(ctx, tableInfo.Name, filterExpr, exclusiveStartKey, limit)
}