// TaxInDB returns true if a taxon is in the database. func taxInDB(c *cmdapp.Command, db jdh.DB, name, parent string, rank jdh.Rank, valid bool) *jdh.Taxon { args := new(jdh.Values) args.Add(jdh.TaxName, name) if len(parent) != 0 { args.Add(jdh.TaxParent, parent) } if rank != jdh.Unranked { args.Add(jdh.TaxRank, rank.String()) } l, err := db.List(jdh.Taxonomy, args) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } defer l.Close() for { tax := &jdh.Taxon{} if err := l.Scan(tax); err != nil { if err == io.EOF { return nil } } if len(tax.Id) > 0 { if tax.IsValid == valid { return tax } } } }
func trForceRun(c *cmdapp.Command, args []string) { openLocal(c) if len(idFlag) > 0 { phy := phylogeny(c, localDB, idFlag) if len(phy.Id) == 0 { return } trForceProc(c, phy) localDB.Exec(jdh.Commit, "", nil) return } l, err := localDB.List(jdh.Trees, new(jdh.Values)) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } for { phy := &jdh.Phylogeny{} if err := l.Scan(phy); err != nil { if err == io.EOF { break } fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } if len(phy.Id) == 0 { continue } trForceProc(c, phy) } localDB.Exec(jdh.Commit, "", nil) }
func txSetRun(c *cmdapp.Command, args []string) { openLocal(c) var tax *jdh.Taxon if len(idFlag) > 0 { tax = taxon(c, localDB, idFlag) if len(tax.Id) == 0 { return } } else if (len(args) > 0) && (strings.Index(args[0], "=") < 0) { name := args[0] pName := "" args = args[1:] if (len(args) > 0) && (strings.Index(args[0], "=") < 0) { pName = args[0] args = args[1:] } tax = pickTaxName(c, localDB, name, pName) if len(tax.Id) == 0 { return } } else { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr("expectiong taxon name or id")) c.Usage() } vals := valsFromArgs(tax.Id, args) localDB.Exec(jdh.Set, jdh.Taxonomy, vals) localDB.Exec(jdh.Commit, "", nil) }
func txSyncPopDesc(c *cmdapp.Command, l jdh.ListScanner, p *jdh.Taxon) { pId := p.Id if !p.IsValid { pId = p.Parent } for { desc := &jdh.Taxon{} if err := l.Scan(desc); err != nil { if err == io.EOF { break } fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } // check if the taxon is in the database if d := taxon(c, localDB, extDBFlag+":"+desc.Id); len(d.Id) != 0 { continue } // adds the new taxon tax := &jdh.Taxon{} *tax = *desc tax.Id = "" tax.Parent = pId tax.Extern = []string{extDBFlag + ":" + desc.Id} if _, err := localDB.Exec(jdh.Add, jdh.Taxonomy, tax); err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } } }
func trForceProc(c *cmdapp.Command, phy *jdh.Phylogeny) { txLs := list.New() vals := new(jdh.Values) vals.Add(jdh.TreTaxon, phy.Id) l, err := localDB.List(jdh.Trees, vals) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } for { var tId jdh.IdElement if err := l.Scan(&tId); err != nil { if err == io.EOF { break } fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } if len(tId.Id) == 0 { continue } txLs.PushBack(tId.Id) } if txLs.Len() == 0 { return } root := phyloNode(c, localDB, phy.Root) trForceNode(c, root, txLs) }
func trLsRun(c *cmdapp.Command, args []string) { openLocal(c) if len(nodeFlag) > 0 { trLsNodes(c) return } l, err := localDB.List(jdh.Trees, new(jdh.Values)) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } for { phy := &jdh.Phylogeny{} if err := l.Scan(phy); err != nil { if err == io.EOF { break } fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } if machineFlag { fmt.Fprintf(os.Stdout, "%s\n", phy.Id) continue } if verboseFlag { fmt.Fprintf(os.Stdout, "%s\t%s\troot: %s\n", phy.Id, phy.Name, phy.Root) continue } fmt.Fprintf(os.Stdout, "%s\troot: %s\n", phy.Name, phy.Root) } }
func getValidParent(c *cmdapp.Command, extId string) string { args := new(jdh.Values) args.Add(jdh.TaxParents, extId) l, err := extDB.List(jdh.Taxonomy, args) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } defer l.Close() for { et := &jdh.Taxon{} if err := l.Scan(et); err != nil { if err == io.EOF { break } fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } p := taxon(c, localDB, extDBFlag+":"+et.Id) if len(p.Id) > 0 { if p.IsValid { return p.Id } else { return p.Parent } } } return "" }
func dsInRun(c *cmdapp.Command, args []string) { openLocal(c) format := "txt" if len(formatFlag) > 0 { format = formatFlag } if len(args) > 0 { switch format { case "txt": for _, fname := range args { dsInTxt(c, fname) } default: fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr("format "+format+" unknown")) os.Exit(1) } } else { switch format { case "txt": dsInTxt(c, "") default: fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr("format "+format+" unknown")) os.Exit(1) } } localDB.Exec(jdh.Commit, "", nil) }
// IsInParentList search an id in the list of parents of the taxon. func isInParentList(c *cmdapp.Command, db jdh.DB, id string, pIds []string) bool { args := new(jdh.Values) args.Add(jdh.TaxParents, id) pl, err := db.List(jdh.Taxonomy, args) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } defer pl.Close() for { p := &jdh.Taxon{} if err := pl.Scan(p); err != nil { if err == io.EOF { break } fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } for _, pid := range pIds { if p.Id == pid { return true } } } return false }
func dsInTxt(c *cmdapp.Command, fname string) { var in *bufio.Reader if len(fname) > 0 { f, err := os.Open(fname) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) return } defer f.Close() in = bufio.NewReader(f) } else { in = bufio.NewReader(os.Stdin) } for { tn, err := readLine(in) if err != nil { break } ln := strings.Join(tn, " ") set := &jdh.Dataset{ Title: ln, } id, err := localDB.Exec(jdh.Add, jdh.Datasets, set) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) continue } if verboseFlag { fmt.Fprintf(os.Stdout, "%s %s\n", id, set.Title) } } }
// RasList returns a raster distribution list scanner. func rasList(c *cmdapp.Command, db jdh.DB, vals *jdh.Values) jdh.ListScanner { l, err := localDB.List(jdh.RasDistros, vals) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } return l }
// SpeList returns an specimen list scanner. func speList(c *cmdapp.Command, db jdh.DB, vals *jdh.Values) jdh.ListScanner { l, err := db.List(jdh.Specimens, vals) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } return l }
// openDB opens a database. func openDB(c *cmdapp.Command, driver, par string) jdh.DB { db, err := jdh.Open(driver, par) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } return db }
func trForceNode(c *cmdapp.Command, nod *jdh.Node, txLs *list.List) { vals := new(jdh.Values) vals.Add(jdh.NodChildren, nod.Id) l, err := localDB.List(jdh.Nodes, vals) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } childs := 0 for { desc := &jdh.Node{} if err := l.Scan(desc); err != nil { if err == io.EOF { break } fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } trForceNode(c, desc, txLs) childs++ } if childs > 1 { return } if len(nod.Taxon) == 0 { return } tax := taxon(c, localDB, nod.Taxon) if tax.IsValid { return } par := taxon(c, localDB, tax.Parent) todel := false for e := txLs.Front(); e != nil; e = e.Next() { tId := e.Value.(string) if tId == par.Id { todel = true break } } if todel { fmt.Fprintf(os.Stdout, "%s: deleted\n", tax.Name) if !repFlag { vals.Reset() vals.Add(jdh.KeyId, nod.Id) localDB.Exec(jdh.Delete, jdh.Nodes, vals) } return } fmt.Fprintf(os.Stdout, "%s: changed to: %s\n", tax.Name, par.Name) if !repFlag { vals.Reset() vals.Add(jdh.KeyId, nod.Id) vals.Add(jdh.NodTaxon, par.Id) localDB.Exec(jdh.Set, jdh.Nodes, vals) txLs.PushBack(par.Id) } }
func spPopFetch(c *cmdapp.Command, tax *jdh.Taxon, prevRank, rank jdh.Rank) { r := tax.Rank if r == jdh.Unranked { r = prevRank } defer func() { l := getTaxDesc(c, localDB, tax.Id, true) spPopNav(c, l, r, rank) l = getTaxDesc(c, localDB, tax.Id, false) spPopNav(c, l, r, rank) }() if len(tax.Id) == 0 { return } if r < rank { return } eid := searchExtern(extDBFlag, tax.Extern) if len(eid) == 0 { return } vals := new(jdh.Values) vals.Add(jdh.SpeTaxon, eid) if geoRefFlag { vals.Add(jdh.SpeGeoref, "true") } l := speList(c, extDB, vals) for { spe := &jdh.Specimen{} if err := l.Scan(spe); err != nil { if err == io.EOF { break } fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } if osp := specimen(c, localDB, extDBFlag+":"+spe.Id); len(osp.Id) > 0 { continue } if len(spe.Catalog) > 0 { if osp := specimen(c, localDB, spe.Catalog); len(osp.Id) > 0 { exsp := searchExtern(extDBFlag, osp.Extern) if exsp == spe.Id { continue } fmt.Fprintf(os.Stderr, "specimen %s already in database as %s [duplicated in %s]\n", spe.Catalog, osp.Id, extDBFlag) continue } } addToSpecimens(c, spe, tax.Id) } }
func txSyncRankNav(c *cmdapp.Command, l jdh.ListScanner, rank jdh.Rank) { for { desc := &jdh.Taxon{} if err := l.Scan(desc); err != nil { if err == io.EOF { break } fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } txSyncRankSet(c, desc, rank) } }
func spGrefNav(c *cmdapp.Command, l jdh.ListScanner, gzt geography.Gazetter) { for { desc := &jdh.Taxon{} if err := l.Scan(desc); err != nil { if err == io.EOF { break } fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } spGrefProc(c, desc, gzt) } }
func trDelNode(c *cmdapp.Command) { vals := new(jdh.Values) if colpFlag { vals.Add(jdh.NodCollapse, nodeFlag) } else { vals.Add(jdh.KeyId, nodeFlag) } if _, err := localDB.Exec(jdh.Delete, jdh.Nodes, vals); err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } localDB.Exec(jdh.Commit, "", nil) }
func spPopNav(c *cmdapp.Command, l jdh.ListScanner, prevRank, rank jdh.Rank) { for { desc := &jdh.Taxon{} if err := l.Scan(desc); err != nil { if err == io.EOF { break } fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } spPopFetch(c, desc, prevRank, rank) } }
func raMkNav(c *cmdapp.Command, l jdh.ListScanner, spDB jdh.DB, prevRank, rank jdh.Rank, size float64) { for { desc := &jdh.Taxon{} if err := l.Scan(desc); err != nil { if err == io.EOF { break } fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } raMkFetch(c, spDB, desc, prevRank, rank, size) } }
func dsSetRun(c *cmdapp.Command, args []string) { if len(idFlag) == 0 { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr("expectiong dataset id")) c.Usage() } openLocal(c) set := dataset(c, localDB, idFlag) if len(set.Id) == 0 { return } vals := valsFromArgs(set.Id, args) localDB.Exec(jdh.Set, jdh.Datasets, vals) localDB.Exec(jdh.Commit, "", nil) }
// GetTaxDesc return the list of descendants of a taxon. func getTaxDesc(c *cmdapp.Command, db jdh.DB, id string, valid bool) jdh.ListScanner { args := new(jdh.Values) if valid { args.Add(jdh.TaxChildren, id) } else { args.Add(jdh.TaxSynonyms, id) } l, err := db.List(jdh.Taxonomy, args) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } return l }
func txTaxoRun(c *cmdapp.Command, args []string) { var db jdh.DB if len(extDBFlag) != 0 { openExt(c, extDBFlag, "") db = extDB } else { openLocal(c) db = localDB } var tax *jdh.Taxon if len(idFlag) > 0 { tax = taxon(c, db, idFlag) if len(tax.Id) == 0 { return } } else if len(args) > 0 { if len(args) > 2 { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr("too many arguments")) os.Exit(1) } pName := "" if len(args) > 1 { pName = args[1] } tax = pickTaxName(c, db, args[0], pName) if len(tax.Id) == 0 { return } } else { tax = &jdh.Taxon{} } if len(formatFlag) > 0 { switch formatFlag { case "txt": case "html": fmt.Fprintf(os.Stdout, "<html>\n") fmt.Fprintf(os.Stdout, "<head><meta http-equiv=\"Content-Type\" content=\"text/html\" charset=utf-8\" /></head>\n") fmt.Fprintf(os.Stdout, "<body bgcolor=\"white\">\n<font face=\"sans-serif\"><pre>\n") default: fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr("unknown format")) os.Exit(1) } } else { formatFlag = "txt" } txTaxoProc(c, db, tax, jdh.Kingdom) if formatFlag == "html" { fmt.Fprintf(os.Stdout, "</pre></font>\n</body>\n</html>\n") } }
func dsDelRun(c *cmdapp.Command, args []string) { if len(idFlag) == 0 { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr("expectiong dataset id")) c.Usage() } openLocal(c) vals := new(jdh.Values) vals.Add(jdh.KeyId, idFlag) if _, err := localDB.Exec(jdh.Delete, jdh.Datasets, vals); err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } localDB.Exec(jdh.Commit, "", nil) }
func raSetRun(c *cmdapp.Command, args []string) { if len(idFlag) == 0 { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr("expectiong specimen id")) c.Usage() } openLocal(c) ras := raster(c, localDB, idFlag) if len(ras.Id) == 0 { return } vals := valsFromArgs(ras.Id, args) localDB.Exec(jdh.Set, jdh.RasDistros, vals) localDB.Exec(jdh.Commit, "", nil) }
func trInTnt(c *cmdapp.Command, fname, pId string) { var in *bufio.Reader if len(fname) > 0 { f, err := os.Open(fname) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } defer f.Close() in = bufio.NewReader(f) } else { in = bufio.NewReader(os.Stdin) } if err := trInSkipTntHead(in); err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } taxLs := make(map[string]string) for { id, err := localDB.Exec(jdh.Add, jdh.Trees, &jdh.Phylogeny{}) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } if _, err = trInReadTreeNode(in, id, "", pId, taxLs); err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } if !trInTntNext(in) { break } } }
func txSyncAddToTaxonomy(c *cmdapp.Command, src *jdh.Taxon) *jdh.Taxon { dest := &jdh.Taxon{} *dest = *src dest.Id = "" dest.Parent = getValidParent(c, src.Id) dest.Extern = []string{extDBFlag + ":" + src.Id} var err error dest.Id, err = localDB.Exec(jdh.Add, jdh.Taxonomy, dest) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } return dest }
func skipNdmTaxon(c *cmdapp.Command, in *bufio.Reader) (string, error) { for { tok, err := readString(in) if err != nil { if err == io.EOF { return "", err } fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } if (tok == "sp") || (tok == ";") || (tok == "groups") || (tok == "map") { return tok, nil } } }
// Taxon gets a taxon. func taxon(c *cmdapp.Command, db jdh.DB, id string) *jdh.Taxon { sc, err := db.Get(jdh.Taxonomy, id) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } tax := &jdh.Taxon{} if err := sc.Scan(tax); err != nil { if err == io.EOF { return &jdh.Taxon{} } fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } return tax }
// Specimen gets an specimen. func specimen(c *cmdapp.Command, db jdh.DB, id string) *jdh.Specimen { sc, err := db.Get(jdh.Specimens, id) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } spe := &jdh.Specimen{} if err := sc.Scan(spe); err != nil { if err == io.EOF { return &jdh.Specimen{} } fmt.Fprintf(os.Stderr, "%s\n", c.ErrStr(err)) os.Exit(1) } return spe }