// Query implements Datastore.Query func (d *Datastore) Query(q query.Query) (query.Results, error) { results := make(chan query.Result) walkFn := func(path string, info os.FileInfo, err error) error { // remove ds path prefix if strings.HasPrefix(path, d.path) { path = path[len(d.path):] } if !info.IsDir() { if strings.HasSuffix(path, ObjectKeySuffix) { path = path[:len(path)-len(ObjectKeySuffix)] } key := ds.NewKey(path) entry := query.Entry{Key: key.String(), Value: query.NotFetched} results <- query.Result{Entry: entry} } return nil } go func() { filepath.Walk(d.path, walkFn) close(results) }() r := query.ResultsWithChan(q, results) r = query.NaiveQueryApply(q, r) return r, nil }
func (fs *Datastore) Query(q query.Query) (query.Results, error) { if (q.Prefix != "" && q.Prefix != "/") || len(q.Filters) > 0 || len(q.Orders) > 0 || q.Limit > 0 || q.Offset > 0 || !q.KeysOnly { // TODO this is overly simplistic, but the only caller is // `ipfs refs local` for now, and this gets us moving. return nil, errors.New("flatfs only supports listing all keys in random order") } reschan := make(chan query.Result, query.KeysOnlyBufSize) go func() { defer close(reschan) err := filepath.Walk(fs.path, func(path string, info os.FileInfo, err error) error { if os.IsNotExist(err) { return nil } if err != nil { log.Errorf("Walk func in Query got error: %v", err) return err } if !info.Mode().IsRegular() || strings.HasPrefix(info.Name(), ".") { return nil } key, ok := fs.decode(info.Name()) if !ok { log.Warning("failed to decode entry in flatfs") return nil } reschan <- query.Result{ Entry: query.Entry{ Key: key.String(), }, } return nil }) if err != nil { log.Warning("walk failed: ", err) } }() return query.ResultsWithChan(q, reschan), nil }