Example #1
0
// AddNode adds a new node to the database.
func (tr *trees) addNode(nod *jdh.Node) (string, error) {
	id := strconv.FormatInt(tr.nxNode, 10)
	nod.Id = id
	if err := tr.valNod(nod); err != nil {
		return "", err
	}
	tr.addValNode(nod)
	tr.nxNode++
	tr.changed = true
	return id, nil
}
Example #2
0
// ValNode validates that a node is valid in the database, and set some
// canonical values. It returns an error if the node is not valid.
func (tr *trees) valNod(nod *jdh.Node) error {
	nod.Id = strings.TrimSpace(nod.Id)
	nod.Tree = strings.TrimSpace(nod.Tree)
	if (len(nod.Id) == 0) || (len(nod.Tree) == 0) {
		return errors.New("node without identification")
	}
	if _, ok := tr.nodes[nod.Id]; ok {
		return fmt.Errorf("node id %s already in use", nod.Id)
	}
	ph, ok := tr.ids[nod.Tree]
	if !ok {
		return fmt.Errorf("node %s in a not assigned phylogeny [id %s]", nod.Id, nod.Tree)
	}
	nod.Parent = strings.TrimSpace(nod.Parent)
	if len(nod.Parent) == 0 {
		if ph.root != nil {
			return fmt.Errorf("node %s without a parent in phylogeny %s", nod.Id, ph.data.Id)
		}
	} else {
		p, ok := ph.nodes[nod.Parent]
		if !ok {
			return fmt.Errorf("node %s without a parent in phylogeny %s", nod.Id, ph.data.Id)
		}
		if (nod.Age > 0) && (p.data.Age < nod.Age) {
			return fmt.Errorf("node %s age %d is older than parent %s age %d", nod.Id, nod.Age, p.data.Id, p.data.Age)
		}
	}
	nod.Taxon = strings.TrimSpace(nod.Taxon)
	if len(nod.Taxon) > 0 {
		if !tr.db.t.isInDB(nod.Taxon) {
			nod.Taxon = ""
		} else if _, ok := ph.taxa[nod.Taxon]; ok {
			return fmt.Errorf("taxon %s assigned to node %s already assigned to phylogeny %s", nod.Taxon, nod.Id, ph.data.Id)
		}
	}
	return nil
}