// 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 }
// 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 }