// Scan implements part of the graphstore.Service interface. // // TODO(fromberger): Maybe use prepared statements here. func (db *DB) Scan(ctx context.Context, req *spb.ScanRequest, f graphstore.EntryFunc) (err error) { var rows *sql.Rows factPrefix := likeEscaper.Replace(req.FactPrefix) + "%" if req.GetTarget() != nil { if req.EdgeKind == "" { rows, err = db.Query("SELECT "+columns+" FROM "+tableName+` WHERE fact LIKE ? ESCAPE '\t' AND source_signature = ? AND source_corpus = ? AND source_root = ? AND source_language = ? AND source_path = ? `+orderByClause, factPrefix, req.Target.Signature, req.Target.Corpus, req.Target.Root, req.Target.Language, req.Target.Path) } else { rows, err = db.Query("SELECT "+columns+" FROM "+tableName+` WHERE fact LIKE ? ESCAPE '\t' AND source_signature = ? AND source_corpus = ? AND source_root = ? AND source_language = ? AND source_path = ? AND kind = ? `+orderByClause, factPrefix, req.Target.Signature, req.Target.Corpus, req.Target.Root, req.Target.Language, req.Target.Path, req.EdgeKind) } } else { if req.EdgeKind == "" { rows, err = db.Query("SELECT "+columns+" FROM "+tableName+" WHERE fact LIKE ? ESCAPE '\t' "+orderByClause, factPrefix) } else { rows, err = db.Query("SELECT "+columns+" FROM "+tableName+` WHERE fact LIKE ? ESCAPE '\t' AND kind = ? `+orderByClause, factPrefix, req.EdgeKind) } } if err != nil { return err } return scanEntries(rows, f) }
// EntryMatchesScan reports whether entry belongs in the result set for req. func EntryMatchesScan(req *spb.ScanRequest, entry *spb.Entry) bool { return (req.GetTarget() == nil || compare.VNamesEqual(entry.Target, req.Target)) && (req.EdgeKind == "" || entry.EdgeKind == req.EdgeKind) && strings.HasPrefix(entry.FactName, req.FactPrefix) }