Example #1
0
// Validate validates that a taxon is valid in the database, and set some
// canonical values. It returns an error if the taxon is not valid.
func (t *taxonomy) validate(tax *jdh.Taxon) error {
	tax.Id = strings.TrimSpace(tax.Id)
	tax.Name = strings.Join(strings.Fields(tax.Name), " ")
	if (len(tax.Id) == 0) || (len(tax.Name) == 0) {
		return errors.New("taxon without identification")
	}
	if _, ok := t.ids[tax.Id]; ok {
		return fmt.Errorf("taxon id %s already in use", tax.Id)
	}
	p := t.root
	if tax.Rank > jdh.Species {
		tax.Rank = jdh.Unranked
	}
	if len(tax.Parent) > 0 {
		var ok bool
		if p, ok = t.ids[tax.Parent]; !ok {
			return fmt.Errorf("taxon %s parent [%s] not in database", tax.Name, tax.Parent)
		}
	}
	if p == t.root {
		if !tax.IsValid {
			return fmt.Errorf("taxon %s is a synonym without a parent", tax.Name)
		}
	} else if !p.data.IsValid {
		return fmt.Errorf("taxon %s parent [%s] is a synonym", tax.Name, p.data.Name)
	}
	if !p.isDescValid(tax.Rank, tax.IsValid) {
		return fmt.Errorf("taxon %s rank incompatible with database hierarchy", tax.Name)
	}
	ext := tax.Extern
	tax.Extern = nil
	for _, e := range ext {
		serv, id, err := jdh.ParseExtern(e)
		if err != nil {
			continue
		}
		if len(id) == 0 {
			continue
		}
		add := true
		for _, ex := range tax.Extern {
			if strings.HasPrefix(ex, serv) {
				add = false
				break
			}
		}
		if !add {
			continue
		}
		if _, ok := t.ids[e]; !ok {
			tax.Extern = append(tax.Extern, e)
		}
	}
	return nil
}
Example #2
0
// Add adds a new taxon to the database.
func (t *taxonomy) add(tax *jdh.Taxon) (string, error) {
	id := strconv.FormatInt(t.next, 10)
	tax.Id = id
	if err := t.validate(tax); err != nil {
		return "", err
	}
	t.addTaxon(tax)
	t.next++
	t.changed = true
	return id, nil
}