// assumes there is a S name field in the concept
sclass NameBasedVoiceCRUD {
transient Concepts cc = db_mainConcepts();
Class conceptClass;
S concept, concepts; // singular & plural of what we are managing
transient A selected;
*() {}
*(Class *conceptClass, S conceptName) {
concept = conceptName;
concepts = plural(conceptName);
}
S answer(S s) null {
new Matches m;
if (match("how many \*concepts*/", s))
ret str(countConcepts(cc, conceptClass));
if (match("delete \*concept*/ *", s, m)) {
S name = $1;
select(null);
A sc = findConceptWithName(name);
if (sc == null)
ret format("\*firstToUpper(concept)*/ * not found", name);
unregisterConcept(sc);
addUndo(new UndoDeleteConcept(sc));
ret format("Scenario * deleted", name);
}
if (match("new \*concept*/ *", s, m)) {
S name = $1;
A sc = conceptWhereCI(cc, conceptClass, +name);
if (sc != null)
ret format("\*firstToUpper(concept)*/ * exists", name);
A a = uniqCI(cc, conceptClass, +name);
select(a);
addUndo(new UndoCreateConcept(a.id));
ret format("\*firstToUpper(concept)*/ * created", name);
}
if (match("list \*concepts*/", s))
ret or2(joinWithComma(collect name(list(cc, conceptClass))), "No \*concepts*/ defined");
if (match("rename \*concept*/ * to *", s, m)) {
S name1 = $1, name2 = $2;
if (!eqic(name1, name2)
&& conceptWhereCI(conceptClass, name := name2) != null)
ret format("A \*concept*/ named * exists", name2);
A sc = findConceptWithName(name1);
if (sc == null)
ret format("\*firstToUpper(concept)*/ * not found", name1);
addUndo(new UndoSetConceptField(sc.id, 'name, name1, name2));
cset(sc, name := name2);
ret format("\*firstToUpper(concept)*/ * renamed to *", name1, name2);
}
}
// this is more of a search function, not an exact name lookup
swappable A findConceptWithName(S name) {
ret conceptWhereCI(cc, conceptClass, +name);
}
swappable void addUndo(UndoableWithAnswer undo) {}
swappable void select(A a) { selected = a; }
}