Лекция 12:
Язык запросов
Добавление данных
Далее создается класс addData, который обрабатывает процедуру получения новых сведений от пользователя и запись их в базу данных (листинги 12.16–12.18).
predicates addNewPerson: () determ.Пример 12.16. Интерфейс addData
constructors new: (readData).Пример 12.17. Декларация класса addData
open core, console facts rd : readData. clauses new(RD):- rd := RD. addNewPerson():- addPerson(Id, Sex), addSpouse(Id, Sex). predicates addPerson: (unsigned Id [out], string Sex [out]) determ. addSpouse: (unsigned Id, string Sex). addSpouse: (unsigned Id, string Sex, unsigned IdS). clauses addPerson(Id, Sex):- Name = rd:readName(), Surname = rd:readSurname(), Sex = rd:readSex(), IdF = rd:readFather(), IdM = rd:readMother(), Id = rd:pd:db:getNewId(), rd:pd:db:setPerson(Id, Name, Surname, Sex, IdF, IdM). addSpouse(Id, Sex):- IdS = rd:readSpouse(Sex), addSpouse(Id, Sex, IdS). addSpouse(_, _, 0):- !. addSpouse(Id, dbrel::male, IdS):- !, rd:pd:db:setSpouse(Id, IdS). addSpouse(Id, _, IdS):- rd:pd:db:setSpouse(IdS, Id).Пример 12.18. Имплементация класса addData
Удаление данных
После этого создается класс delData, который занимается удалением записей из базы данных (листинги 12.19–12.21).
predicates delPerson: () determ.Пример 12.19. Интерфейс delData
Конструктор выглядит следующим образом:
constructors new: (readData).Пример 12.20. Декларация класса delData
open core, console facts rd : readData. clauses new(RD):- rd := RD. delPerson():- Id = rd:getIdFromUser(), Sex = rd:pd:db:getSex(Id), rd:pd:db:delPerson(Id), delSpouses(Id, Sex). predicates delSpouses: (unsigned Id, string Sex). clauses delSpouses(Id, dbrel::male):- !, foreach rd:pd:db:spouse_nd(Id, IdS) do rd:pd:db:delSpouse(Id, IdS) end foreach. delSpouses(Id, _):- foreach rd:pd:db:spouse_nd(IdS, Id) do rd:pd:db:delSpouse(IdS, Id) end foreach.Пример 12.21. Имплементация класса delData
Деревья предков и потомков
Для построения и вывода на печать деревьев предков и потомков создается класс trees (листинги 12.22–12.24).
predicates findAncTree: () determ. findDescTree: () determ.Пример 12.22. Интерфейс trees
constructors new: (readData).Пример 12.23. Декларация класса trees
open core, console facts rd : readData. rel : relation. clauses new(RD):- rd := RD, rel := relation::new(rd:pd:db). findAncTree():- Id = rd:getIdFromUser(), AncTree = createBTree(Id), printBTree(AncTree). findDescTree():- Id = rd:getIdFromUser(), Tree = createTree(Id), printTree(Tree). domains btree = bt(btree, unsigned, btree); nil. tree = t(unsigned, tree*). predicates createBTree: (unsigned) -> btree. createTree: (unsigned) -> tree. printBTree: (btree). printBTree: (btree, charCount). printTree: (tree). printTree: (tree, charCount). printElem: (unsigned, charCount). clauses createBTree(I) = bt(L, I, R):- L = if rel:father(F, I), ! then createBTree(F) else nil end if, R = if rel:mother(M, I), ! then createBTree(M) else nil end if. createTree(Id) = t(Id, list::map([I || rel:parent(Id, I)], {(C) = createTree(C)})). printBTree(Tree):- printBTree(Tree, 0). printBTree(bt(LT, Id, RT), N):- printBTree(LT, N + 1), printElem(Id, N), printBTree(RT, N + 1). printBTree(nil, _). printTree(Tree):- printTree(Tree, 0). printTree(t(Id, TL), N):- printElem(Id, N), list::forAll(TL, {(T):- printTree(T, N + 1)}). printElem(Id, N):- write(string::create(N, "\t"), rd:pd:getName(Id)), nl.Пример 12.24. Имплементация класса trees
Запросы к базе данных
Наконец, создается класс query для обработки запросов к базе данных (листинги 12.25–12.27).
predicates query: () determ.Пример 12.25. Интерфейс query
constructors new: (readData, relation).Пример 12.26. Декларация класса query
open core, console facts rd : readData. rel : relation. clauses new(RD, Rel):- rd := RD, rel := Rel. query():- write("Введите запрос:\n"), Str = rd:readNonEmptyStr(), P = parser::new(rd:pd:db), Term = P:parse(Str), write(Term), nl, C = calculation::new(rel), Res = C:calc(Term), Answer = rd:pd:getNamesStr(Res), write(Answer), nl.Пример 12.27. Имплементация класса query