Add "not" variants for --linked-by and --linking-to

pull/6/head
Mickaël Menu 3 years ago
parent 92afd77fd7
commit f7a5c04c6e
No known key found for this signature in database
GPG Key ID: 53D73664CD359895

@ -371,33 +371,45 @@ func (d *NoteDAO) findRows(opts note.FinderOpts) (*sql.Rows, error) {
whereExprs = append(whereExprs, strings.Join(globs, " AND "))
case note.LinkedByFilter:
ids, err := d.findIdsByPathPrefixes(filter)
ids, err := d.findIdsByPathPrefixes(filter.Paths)
if err != nil {
return nil, err
}
if len(filter) == 0 {
if len(ids) == 0 {
break
}
whereExprs = append(whereExprs, fmt.Sprintf(
"n.id IN (SELECT target_id FROM links WHERE source_id IN %v)",
"("+strutil.JoinInt64(ids, ",")+")"),
expr := "n.id"
if filter.Negate {
expr += " NOT"
}
expr += fmt.Sprintf(
" IN (SELECT target_id FROM links WHERE target_id IS NOT NULL AND source_id IN %v)",
"("+strutil.JoinInt64(ids, ",")+")",
)
whereExprs = append(whereExprs, expr)
case note.LinkingToFilter:
ids, err := d.findIdsByPathPrefixes(filter)
ids, err := d.findIdsByPathPrefixes(filter.Paths)
if err != nil {
return nil, err
}
if len(filter) == 0 {
if len(ids) == 0 {
break
}
whereExprs = append(whereExprs, fmt.Sprintf(
"n.id IN (SELECT source_id FROM links WHERE target_id IN %v)",
"("+strutil.JoinInt64(ids, ",")+")"),
expr := "n.id"
if filter.Negate {
expr += " NOT"
}
expr += fmt.Sprintf(
" IN (SELECT source_id FROM links WHERE target_id IN %v)",
"("+strutil.JoinInt64(ids, ",")+")",
)
whereExprs = append(whereExprs, expr)
case note.DateFilter:
value := "?"
field := "n." + dateField(filter)

@ -494,21 +494,39 @@ func TestNoteDAOFindExcludingMultiplePaths(t *testing.T) {
func TestNoteDAOFindLinkedBy(t *testing.T) {
testNoteDAOFindPaths(t,
note.FinderOpts{
Filters: []note.Filter{note.LinkedByFilter([]string{"f39c8.md", "log/2021-01-03"})},
Filters: []note.Filter{note.LinkedByFilter{Paths: []string{"f39c8.md", "log/2021-01-03"}, Negate: false}},
},
[]string{"ref/test/a.md", "log/2021-01-03.md", "log/2021-01-04.md"},
)
}
func TestNoteDAOFindNotLinkedBy(t *testing.T) {
testNoteDAOFindPaths(t,
note.FinderOpts{
Filters: []note.Filter{note.LinkedByFilter{Paths: []string{"f39c8.md", "log/2021-01-03"}, Negate: true}},
},
[]string{"ref/test/b.md", "f39c8.md", "log/2021-02-04.md", "index.md"},
)
}
func TestNoteDAOFindLinkingTo(t *testing.T) {
testNoteDAOFindPaths(t,
note.FinderOpts{
Filters: []note.Filter{note.LinkingToFilter([]string{"log/2021-01-04", "ref/test/a.md"})},
Filters: []note.Filter{note.LinkingToFilter{Paths: []string{"log/2021-01-04", "ref/test/a.md"}, Negate: false}},
},
[]string{"f39c8.md", "log/2021-01-03.md"},
)
}
func TestNoteDAOFindNotLinkingTo(t *testing.T) {
testNoteDAOFindPaths(t,
note.FinderOpts{
Filters: []note.Filter{note.LinkingToFilter{Paths: []string{"log/2021-01-04", "ref/test/a.md"}, Negate: true}},
},
[]string{"ref/test/b.md", "ref/test/a.md", "log/2021-02-04.md", "index.md", "log/2021-01-04.md"},
)
}
func TestNoteDAOFindCreatedOn(t *testing.T) {
testNoteDAOFindPaths(t,
note.FinderOpts{

@ -21,6 +21,8 @@ type Filtering struct {
ModifiedAfter string `help:"Only the notes modified after the given date" placeholder:"<date>"`
LinkedBy []string `help:"Only the notes linked by the given notes" placeholder:"<path>" short:"l"`
LinkingTo []string `help:"Only the notes linking to the given notes" placeholder:"<path>" short:"L"`
NotLinkedBy []string `help:"Only the notes not linked by the given notes" placeholder:"<path>"`
NotLinkingTo []string `help:"Only the notes not linking to the given notes" placeholder:"<path>"`
Exclude []string `help:"Excludes notes matching the given file path pattern from the list" short:"x" placeholder:"<glob>"`
Interactive bool `help:"Further filter the list of notes interactively" short:"i"`
}
@ -122,12 +124,34 @@ func NewFinderOpts(zk *zk.Zk, filtering Filtering, sorting Sorting) (*note.Finde
linkedByPaths, ok := relPaths(zk, filtering.LinkedBy)
if ok {
filters = append(filters, note.LinkedByFilter(linkedByPaths))
filters = append(filters, note.LinkedByFilter{
Paths: linkedByPaths,
Negate: false,
})
}
linkingToPaths, ok := relPaths(zk, filtering.LinkingTo)
if ok {
filters = append(filters, note.LinkingToFilter(linkingToPaths))
filters = append(filters, note.LinkingToFilter{
Paths: linkingToPaths,
Negate: false,
})
}
notLinkedByPaths, ok := relPaths(zk, filtering.NotLinkedBy)
if ok {
filters = append(filters, note.LinkedByFilter{
Paths: notLinkedByPaths,
Negate: true,
})
}
notLinkingToPaths, ok := relPaths(zk, filtering.NotLinkingTo)
if ok {
filters = append(filters, note.LinkingToFilter{
Paths: notLinkingToPaths,
Negate: true,
})
}
if filtering.Interactive {

@ -41,10 +41,16 @@ type PathFilter []string
type ExcludePathFilter []string
// LinkedByFilter is a note filter used to select notes being linked by another one.
type LinkedByFilter []string
type LinkedByFilter struct {
Paths []string
Negate bool
}
// LinkingToFilter is a note filter used to select notes being linked by another one.
type LinkingToFilter []string
type LinkingToFilter struct {
Paths []string
Negate bool
}
// DateFilter can be used to filter notes created or modified before, after or on a given date.
type DateFilter struct {

Loading…
Cancel
Save