// EnsureReverseEdges checks if gs contains reverse edges. If it doesn't, it // will scan gs for all forward edges, adding a reverse for each back into the // GraphStore. This is necessary for a GraphStoreService to work properly. func EnsureReverseEdges(ctx context.Context, gs graphstore.Service) error { var edge *spb.Entry if err := gs.Scan(ctx, &spb.ScanRequest{}, func(e *spb.Entry) error { if graphstore.IsEdge(e) { edge = e return io.EOF } return nil }); err != nil { return err } if edge == nil { log.Println("No edges found in GraphStore") return nil } else if schema.EdgeDirection(edge.EdgeKind) == schema.Reverse { return nil } var foundReverse bool if err := gs.Read(ctx, &spb.ReadRequest{ Source: edge.Target, EdgeKind: schema.MirrorEdge(edge.EdgeKind), }, func(entry *spb.Entry) error { foundReverse = true return nil }); err != nil { return fmt.Errorf("error checking for reverse edge: %v", err) } if foundReverse { return nil } return addReverseEdges(ctx, gs) }
func readEntries(ctx context.Context, gs graphstore.Service, entryFunc graphstore.EntryFunc, edgeKind string, tickets []string) error { for _, ticket := range tickets { src, err := kytheuri.ToVName(ticket) if err != nil { return fmt.Errorf("error parsing ticket %q: %v", ticket, err) } if err := gs.Read(ctx, &spb.ReadRequest{ Source: src, EdgeKind: edgeKind, }, entryFunc); err != nil { return fmt.Errorf("GraphStore Read error for ticket %q: %v", ticket, err) } } return nil }
// getEdges returns edgeTargets with the given node as their source. Only edge // entries that return true when applied to pred are returned. func getEdges(ctx context.Context, gs graphstore.Service, node *spb.VName, pred func(*spb.Entry) bool) ([]*edgeTarget, error) { var targets []*edgeTarget if err := gs.Read(ctx, &spb.ReadRequest{ Source: node, EdgeKind: "*", }, func(entry *spb.Entry) error { if graphstore.IsEdge(entry) && pred(entry) { targets = append(targets, &edgeTarget{entry.EdgeKind, entry.Target}) } return nil }); err != nil { return nil, fmt.Errorf("read error: %v", err) } return targets, nil }
func getSourceText(ctx context.Context, gs graphstore.Service, fileVName *spb.VName) (text []byte, encoding string, err error) { if err := gs.Read(ctx, &spb.ReadRequest{Source: fileVName}, func(entry *spb.Entry) error { switch entry.FactName { case schema.TextFact: text = entry.FactValue case schema.TextEncodingFact: encoding = string(entry.FactValue) default: // skip other file facts } return nil }); err != nil { return nil, "", fmt.Errorf("read error: %v", err) } if text == nil { err = fmt.Errorf("file not found: %+v", fileVName) } return }