예제 #1
0
func (m *Map) ensureDir(corpus, root, path string) *ftpb.DirectoryReply {
	dirs := m.ensureCorpusRoot(corpus, root)
	dir := dirs[path]
	if dir == nil {
		dir = &ftpb.DirectoryReply{}
		dirs[path] = dir

		if path != "/" {
			parent := m.ensureDir(corpus, root, filepath.Dir(path))
			uri := kytheuri.URI{
				Corpus: corpus,
				Root:   root,
				Path:   path,
			}
			parent.Subdirectory = addToSet(parent.Subdirectory, uri.String())
		}
	}
	return dir
}
예제 #2
0
func displayCorpusRoots(cr *ftpb.CorpusRootsReply) error {
	if *displayJSON {
		return jsonMarshaler.Marshal(out, cr)
	}

	for _, c := range cr.Corpus {
		for _, root := range c.Root {
			var err error
			if lsURIs {
				uri := kytheuri.URI{
					Corpus: c.Name,
					Root:   root,
				}
				_, err = fmt.Fprintln(out, uri.String())
			} else {
				_, err = fmt.Fprintln(out, filepath.Join(c.Name, root))
			}
			if err != nil {
				return err
			}
		}
	}
	return nil
}
예제 #3
0
// Edges implements part of the xrefs.Service interface.
func (db *DB) Edges(req *xpb.EdgesRequest) (*xpb.EdgesReply, error) {
	if req.PageSize != 0 || req.PageToken != "" {
		return nil, errors.New("edge pages unimplemented for SQL DB")
	}
	reply := &xpb.EdgesReply{}

	allowedKinds := stringset.New(req.Kind...)

	nodeTickets := stringset.New()
	for _, t := range req.Ticket {
		uri, err := kytheuri.Parse(t)
		if err != nil {
			return nil, err
		}

		edges := make(map[string]stringset.Set)
		var (
			target kytheuri.URI
			kind   string
		)

		rows, err := db.edgesStmt.Query(uri.Signature, uri.Corpus, uri.Root, uri.Path, uri.Language)
		if err != nil {
			rows.Close()
			return nil, fmt.Errorf("forward edges query error: %v", err)
		}
		for rows.Next() {
			if err := rows.Scan(&target.Signature, &target.Corpus, &target.Root, &target.Path, &target.Language, &kind); err != nil {
				rows.Close()
				return nil, fmt.Errorf("forward edges scan error: %v", err)
			} else if len(allowedKinds) != 0 && !allowedKinds.Contains(kind) {
				continue
			}

			targets, ok := edges[kind]
			if !ok {
				targets = stringset.New()
				edges[kind] = targets
			}

			ticket := target.String()
			targets.Add(ticket)
			nodeTickets.Add(ticket)
		}
		if err := rows.Close(); err != nil {
			return nil, err
		}

		rows, err = db.revEdgesStmt.Query(uri.Signature, uri.Corpus, uri.Root, uri.Path, uri.Language)
		if err != nil {
			rows.Close()
			return nil, fmt.Errorf("reverse edges query error: %v", err)
		}
		for rows.Next() {
			if err := rows.Scan(&target.Signature, &target.Corpus, &target.Root, &target.Path, &target.Language, &kind); err != nil {
				rows.Close()
				return nil, fmt.Errorf("reverse edges scan error: %v", err)
			}

			kind = schema.MirrorEdge(kind)
			if len(allowedKinds) != 0 && !allowedKinds.Contains(kind) {
				continue
			}

			targets, ok := edges[kind]
			if !ok {
				targets = stringset.New()
				edges[kind] = targets
			}

			ticket := target.String()
			targets.Add(ticket)
			nodeTickets.Add(ticket)
		}
		if err := rows.Close(); err != nil {
			return nil, err
		}

		var g []*xpb.EdgeSet_Group
		for kind, targets := range edges {
			g = append(g, &xpb.EdgeSet_Group{
				Kind:         kind,
				TargetTicket: targets.Slice(),
			})
		}

		if len(g) != 0 {
			reply.EdgeSet = append(reply.EdgeSet, &xpb.EdgeSet{
				SourceTicket: t,
				Group:        g,
			})
		}
	}

	nodesReply, err := db.Nodes(&xpb.NodesRequest{
		Ticket: nodeTickets.Slice(),
		Filter: req.Filter,
	})
	if err != nil {
		return nil, fmt.Errorf("nodes request error: %v", err)
	}
	reply.Node = nodesReply.Node
	return reply, nil
}
예제 #4
0
// Decorations implements part of the xrefs.Service interface.
func (db *DB) Decorations(req *xpb.DecorationsRequest) (*xpb.DecorationsReply, error) {
	if req.GetLocation() == nil {
		return nil, errors.New("missing location")
	} else if req.Location.Kind != xpb.Location_FILE {
		return nil, fmt.Errorf("%s location kind unimplemented", req.Location.Kind)
	} else if len(req.DirtyBuffer) != 0 {
		return nil, errors.New("dirty buffers unimplemented")
	}

	fileTicket := req.Location.Ticket

	edgesReply, err := db.Edges(&xpb.EdgesRequest{
		Ticket: []string{fileTicket},
		Kind:   []string{revChildOfEdge},
		Filter: []string{schema.NodeKindFact, schema.TextFact, schema.TextEncodingFact},
	})
	if err != nil {
		return nil, err
	}

	reply := &xpb.DecorationsReply{
		Location: &xpb.Location{
			Ticket: fileTicket,
		},
	}

	nodes := xrefs.NodesMap(edgesReply.Node)

	if req.SourceText {
		if nodes[fileTicket] == nil {
			nodesReply, err := db.Nodes(&xpb.NodesRequest{Ticket: []string{fileTicket}})
			if err != nil {
				return nil, err
			}
			nodes = xrefs.NodesMap(nodesReply.Node)
		}
		reply.SourceText = nodes[fileTicket][schema.TextFact]
		reply.Encoding = string(nodes[fileTicket][schema.TextEncodingFact])
	}

	nodeTickets := stringset.New()

	if req.References {
		// Traverse the following chain of edges:
		//   file --%/kythe/edge/childof-> []anchor --forwardEdgeKind-> []target
		edges := xrefs.EdgesMap(edgesReply.EdgeSet)

		for _, anchor := range edges[fileTicket][revChildOfEdge] {
			if string(nodes[anchor][schema.NodeKindFact]) != schema.AnchorKind {
				continue
			}

			uri, err := kytheuri.Parse(anchor)
			if err != nil {
				return nil, fmt.Errorf("invalid anchor ticket found %q: %v", anchor, err)
			}
			rows, err := db.anchorEdgesStmt.Query(schema.ChildOfEdge, uri.Signature, uri.Corpus, uri.Root, uri.Path, uri.Language)
			if err != nil {
				return nil, fmt.Errorf("anchor %q edge query error: %v", anchor, err)
			}

			for rows.Next() {
				var target kytheuri.URI
				var kind string
				if err := rows.Scan(&target.Signature, &target.Corpus, &target.Root, &target.Path, &target.Language, &kind); err != nil {
					return nil, fmt.Errorf("anchor %q edge scan error: %v", anchor, err)
				}
				ticket := target.String()
				reply.Reference = append(reply.Reference, &xpb.DecorationsReply_Reference{
					SourceTicket: anchor,
					Kind:         kind,
					TargetTicket: ticket,
				})
				nodeTickets.Add(anchor, ticket)
			}
		}
	}

	nodesReply, err := db.Nodes(&xpb.NodesRequest{Ticket: nodeTickets.Slice()})
	if err != nil {
		return nil, err
	}
	reply.Node = nodesReply.Node

	return reply, nil
}