Filter by creation date

This commit is contained in:
Mickaël Menu 2021-01-12 19:58:14 +01:00
parent 91118a21ce
commit d797b94845
No known key found for this signature in database
GPG Key ID: 53D73664CD359895
5 changed files with 113 additions and 4 deletions

View File

@ -173,6 +173,18 @@ func (d *NoteDAO) Find(opts note.FinderOpts, callback func(note.Match) error) (i
}
whereExprs = append(whereExprs, strings.Join(globs, " OR "))
case note.DateFilter:
value := "?"
field := "n." + dateField(filter)
op, ignoreTime := dateDirection(filter)
if ignoreTime {
field = "date(" + field + ")"
value = "date(?)"
}
whereExprs = append(whereExprs, fmt.Sprintf("%s %s %s", field, op, value))
args = append(args, filter.Date)
default:
panic("unknown filter type")
}
@ -236,3 +248,27 @@ ON n.id = notes_fts.rowid`
return count, nil
}
func dateField(filter note.DateFilter) string {
switch filter.Field {
case note.DateCreated:
return "created"
case note.DateModified:
return "modified"
default:
panic("unknown DateFilter field")
}
}
func dateDirection(filter note.DateFilter) (op string, ignoreTime bool) {
switch filter.Direction {
case note.DateOn:
return "=", true
case note.DateBefore:
return "<=", false
case note.DateAfter:
return ">=", false
default:
panic("unknown DateFilter direction")
}
}

View File

@ -2,19 +2,24 @@ package cmd
import (
"fmt"
"time"
"github.com/mickael-menu/zk/adapter/sqlite"
"github.com/mickael-menu/zk/core/note"
"github.com/mickael-menu/zk/core/zk"
"github.com/mickael-menu/zk/util/opt"
"github.com/tj/go-naturaldate"
)
// List displays notes matching a set of criteria.
type List struct {
Paths []string `arg optional placeholder:"PATHS"`
Format string `help:"Pretty prints the list using the given format" placeholder:"TEMPLATE"`
Match string `help:"Terms to search for in the notes" placeholder:"TERMS"`
Limit int `help:"Limit the number of results" placeholder:"MAX"`
Paths []string `arg optional placeholder:"PATHS"`
Format string `help:"Pretty prints the list using the given format" placeholder:"TEMPLATE"`
Match string `help:"Terms to search for in the notes" placeholder:"TERMS"`
Limit int `help:"Limit the number of results" placeholder:"MAX"`
Created string `help:"Show only the notes created on the given date" placeholder:"DATE"`
CreatedBefore string `help:"Show only the notes created before the given date" placeholder:"DATE"`
CreatedAfter string `help:"Show only the notes created after the given date" placeholder:"DATE"`
}
func (cmd *List) Run(container *Container) error {
@ -48,6 +53,42 @@ func (cmd *List) Run(container *Container) error {
filters = append(filters, note.MatchFilter(cmd.Match))
}
if cmd.Created != "" {
date, err := parseDate(cmd.Created)
if err != nil {
return err
}
filters = append(filters, note.DateFilter{
Date: date,
Field: note.DateCreated,
Direction: note.DateOn,
})
}
if cmd.CreatedBefore != "" {
date, err := parseDate(cmd.CreatedBefore)
if err != nil {
return err
}
filters = append(filters, note.DateFilter{
Date: date,
Field: note.DateCreated,
Direction: note.DateBefore,
})
}
if cmd.CreatedAfter != "" {
date, err := parseDate(cmd.CreatedAfter)
if err != nil {
return err
}
filters = append(filters, note.DateFilter{
Date: date,
Field: note.DateCreated,
Direction: note.DateAfter,
})
}
count, err := note.List(
note.ListOpts{
Format: opt.NewNotEmptyString(cmd.Format),
@ -76,3 +117,8 @@ func printNote(note string) error {
_, err := fmt.Println(note)
return err
}
func parseDate(date string) (time.Time, error) {
// FIXME: support years
return naturaldate.Parse(date, time.Now().UTC(), naturaldate.WithDirection(naturaldate.Past))
}

View File

@ -18,6 +18,28 @@ type MatchFilter string
// PathFilter is a note filter using path globs to match notes.
type PathFilter []string
// DateFilter can be used to filter notes created or modified before, after or on a given date.
type DateFilter struct {
Date time.Time
Direction DateDirection
Field DateField
}
type DateDirection int
const (
DateOn DateDirection = iota + 1
DateBefore
DateAfter
)
type DateField int
const (
DateCreated DateField = iota + 1
DateModified
)
// Match holds information about a note matching the list filters.
type Match struct {
// Snippet is an excerpt of the note.
@ -166,3 +188,4 @@ type Filter interface{ sealed() }
func (f MatchFilter) sealed() {}
func (f PathFilter) sealed() {}
func (f DateFilter) sealed() {}

1
go.mod
View File

@ -19,6 +19,7 @@ require (
github.com/rogpeppe/go-internal v1.6.2 // indirect
github.com/rvflash/elapsed v0.2.0
github.com/tebeka/strftime v0.1.5 // indirect
github.com/tj/go-naturaldate v1.3.0
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad // indirect
gopkg.in/djherbis/times.v1 v1.2.0
gopkg.in/yaml.v2 v2.4.0 // indirect

3
go.sum
View File

@ -147,6 +147,9 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/tebeka/strftime v0.1.5 h1:1NQKN1NiQgkqd/2moD6ySP/5CoZQsKa1d3ZhJ44Jpmg=
github.com/tebeka/strftime v0.1.5/go.mod h1:29/OidkoWHdEKZqzyDLUyC+LmgDgdHo4WAFCDT7D/Ig=
github.com/tj/assert v0.0.0-20190920132354-ee03d75cd160/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
github.com/tj/go-naturaldate v1.3.0 h1:OgJIPkR/Jk4bFMBLbxZ8w+QUxwjqSvzd9x+yXocY4RI=
github.com/tj/go-naturaldate v1.3.0/go.mod h1:rpUbjivDKiS1BlfMGc2qUKNZ/yxgthOfmytQs8d8hKk=
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/zclconf/go-cty v1.2.0 h1:sPHsy7ADcIZQP3vILvTjrh74ZA175TFP5vqiNK1UmlI=
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=