func (vfs FuseVfs) openQueryEntryDir(path []string) ([]fuse.DirEntry, fuse.Status) { log.Infof(2, "BEGIN openQueryEntryDir(%v)", path) defer log.Infof(2, "END openQueryEntryDir(%v)", path) queryText := path[0] expression, err := query.Parse(queryText) if err != nil { return nil, fuse.ENOENT } tagNames := query.TagNames(expression) tags, err := vfs.store.TagsByNames(tagNames) for _, tagName := range tagNames { if !containsTag(tags, tagName) { return nil, fuse.ENOENT } } files, err := vfs.store.QueryFiles(expression) if err != nil { log.Fatalf("could not query files: %v", err) } entries := make([]fuse.DirEntry, 0, len(files)) for _, file := range files { linkName := vfs.getLinkName(file) entries = append(entries, fuse.DirEntry{Name: linkName, Mode: fuse.S_IFLNK}) } return entries, fuse.OK }
func (vfs FuseVfs) getQueryEntryAttr(path []string) (*fuse.Attr, fuse.Status) { log.Infof(2, "BEGIN getQueryEntryAttr(%v)", path) defer log.Infof(2, "END getQueryEntryAttr(%v)", path) pathLength := len(path) name := path[pathLength-1] if len(path) == 1 && path[0] == queryHelpFilename { now := time.Now() return &fuse.Attr{Mode: fuse.S_IFREG | 0444, Nlink: 1, Size: uint64(len(queryDirHelp)), Mtime: uint64(now.Unix()), Mtimensec: uint32(now.Nanosecond())}, fuse.OK } if len(path) > 1 { fileId := vfs.parseFileId(name) if fileId != 0 { return vfs.getFileEntryAttr(fileId) } return nil, fuse.ENOENT } queryText := path[0] if queryText[len(queryText)-1] == ' ' { // prevent multiple entries for same query when typing path in a GUI return nil, fuse.ENOENT } expression, err := query.Parse(queryText) if err != nil { return nil, fuse.ENOENT } tagNames := query.TagNames(expression) tags, err := vfs.store.TagsByNames(tagNames) for _, tagName := range tagNames { if !containsTag(tags, tagName) { return nil, fuse.ENOENT } } _, _ = vfs.store.AddQuery(queryText) if err := vfs.store.Commit(); err != nil { log.Fatalf("could not commit transaction: %v", err) } now := time.Now() return &fuse.Attr{Mode: fuse.S_IFDIR | 0755, Nlink: 2, Size: uint64(0), Mtime: uint64(now.Unix()), Mtimensec: uint32(now.Nanosecond())}, fuse.OK }
func listFilesForQuery(queryText string, dirOnly, fileOnly, topOnly, leafOnly, recursive, print0, showCount, onePerLine bool) error { if queryText == "" { return fmt.Errorf("query must be specified. Use --all to show all files.") } store, err := storage.Open() if err != nil { return fmt.Errorf("could not open storage: %v", err) } defer store.Close() log.Info(2, "parsing query") expression, err := query.Parse(queryText) if err != nil { return err } log.Info(2, "checking tag names") wereErrors := false tagNames := query.TagNames(expression) tags, err := store.TagsByNames(tagNames) for _, tagName := range tagNames { if !tags.ContainsName(tagName) { log.Warnf("no such tag '%v'.", tagName) wereErrors = true continue } } if wereErrors { return blankError } log.Info(2, "querying database") files, err := store.QueryFiles(expression) if err != nil { return fmt.Errorf("could not query files: %v", err) } if err = listFiles(files, dirOnly, fileOnly, topOnly, leafOnly, recursive, print0, showCount, onePerLine); err != nil { return err } return nil }