logo
TurboProlog / Документация / TOM_1

Обновление базы данных

Основной принцип: вы не можете распространить обновление базы данных

за вашу программу, но можете сохранить базу несколькими определенными ва-

ми предикатами. Это облегчает изменения базы данных и/или добавление но-

вых B-деревьев. Это облегчает также создание корректных систем баз дан-

ных, т.к. ваша программа содержит лишь маленький участок, во время испол-

нения которого база данных незащищена.

Следующий пример показывает обновление двух различных отношений, об-

ъекты которых являются строками:

person(firstname, lastname, street, zipcode)

city(zipcode, cityname)

Обновление происходит с помощью следующих ключей, соответствующих

person и city отношениям:

Person's Name.........Last Name плюс First Name

Person's Address......Street Name

City Number...........Zip Code

В этом примере мы подразумеваем, что B-деревья уже открыты, и что их

bt_selector были установлены в предикате indices. Перед тем как программа

начинает обновление она исключает возможность ситуации BREAK с помощью

предиката break после окончания обновления программа заполняет базу дан-

ных с помощью db_flush. Хотя db_flush делает обновление медленным процес-

сом, это обеспечивает сохранность файла.

Чтобы сделать систему максимально безопасной, программа записывает

изменения в специальном файле с помощью предиката logdbchange.

/* Программа CH15EX05.PRO */

/* Эта программа нуждается в предыдущем фрагменте */

/* "Ведение журнала изменений базы данных" */

domains

dbdom = city(zipcode, cityname);

person(firstname, lastname, street, zipcode, code)

zipcode, cityname, firstname, lastname = string

street, code = string

indexname = person_name; person_adr; city_no

relation = city; person

db_selector = dba; logdba

database

indices(indexname, bt_selector) /* Содержит ключ который

является именем личности или

адресом или номером города;

также содержит селектор

B-дерева */

predicates

xname(firstname, lastname, string) /* Этот предикат создает

имя индексации из

последнего имени (20

символов) и первого имени

(10 символов) */

clauses

xname(F, L, S) :-

str_len(L, Len), Len>20, !,

frontstr(20, L, L1, _),

format(S,"&-20&", L1, F).

xname(F, L, S) :-

format(S, "&-20&", L, F).

predicates

dba_insert(relation, dbdom)

dba_insert(relation, dbdom, ref)

dba_erase(relation, ref).

clauses

dba_insert(person, Term) :- !,

break(OldBreak),

break(off),

indices(person_name, I1),

indices(person_adr, I2), !,

Term = person(Fname, Lname, Adr, _, _),

xname(Fname, Lname, Xname), /* создается именной ключ */

chain_insertz(dba, person, dbdom, Term, Ref),

rey_insert(dba, I1, Xname, Ref), /* вставляется именной

ключ */

rey_insert(dba, I2, Adr, Ref), /* вставляется адресный

ключ для личности */

db_flush(dba),

logdbchange(insert(person, Term, Ref)),

break(OldBreak).

dba_insert(city, Term) :-

break(OldBreak),

break(off),

indices(city_no, I), !,

Term = city(ZipCode,_),

chain_insertz(dba, city, dbdom, Term, Ref),

key_insert(dba, I, ZipCode, Ref),

db_flush(dba),

logdbchange(insert(city, Term, Ref)),

break(OldBreak).

dba_replace(person, NewTerm, Ref) :-!,

break(OldBreak),

break(off),

indices(person_name, I1),

indices(person_adr, I2), !,

ref term(dba, dbdom, Ref, OldTerm),

OldTerm = person(OldFname, OldAdr, _, _),

xname(OldFname, OldLname, OldXname),

key_delete(dba, I1, OldXname, Ref),

key_delete(dba, I2, OldAdr, Ref),

NewTerm = person(NewFname, NewLname, NewAdr, _, _),

xname(NewFname, NewLname, NewXname),

term_replace(dba, dbdom, Ref, NeweTerm),

key_insert(dba, I1, NewXname, Ref),

key_insert(dba, I2, NewAdr, Ref),

db_flush(dba)

logdbchange(replace(person, NewTerm, Ref, OldTerm)),

break(OldBreak).

dba_replace(city, NewTerm, Ref0 :- !,

break(OldBreak),

break(off),

indices(city_no, I), !,

ref term(dba, dbdom, Ref, OldTerm),

OldTerm = city(OldZipCode, _),

key delete(dba, I, OldZipCode, Ref),

NewTerm = city(ZipCode, _),

term replace(dba, dbdom, Ref, NewTerm),

key_insert(dba, I, ZipCode, Ref),

db_flush(dba),

logdbchange(replace(city, NewTerm, Ref, OldTerm)),

break(OldBreak).

dba_erase(person, Ref) :- !,

break(OldBreak),

break(off),

indices(person_name, I1),

indices(person_adr, I2), !,

ref_term(dba, dbdom, Ref, OldTerm),

OldTerm = person(OldFname, OldLname, OldAdr, _, _),

xname(OldFname, OldLname, OldXname),

key_delete(dba, I1, OldXname, Ref),

key_delete(dba, I2, OldAdr, Ref),

term_delete(dba, person, Ref),

db_flush(dba),

logdbchange(erase(person, Ref, OldTerm)),

break(OldBreak).

dba_erase(city, Ref) :-

break(OldBreak),

break(off),

indices(city_no, I), !,

ref_term(dba, dbdom, Ref, OldTerm),

OldTerm = city(OldZipCode, _),

key_delete(dba, I, OldZipCode, Ref),

term_delete(dba, city, Ref),

db_flush(dba),

logdbchange(erase(city, Ref, OldTerm)),

break(OldBreak).