[Перевод] Минимальное DB/GUI приложение на PicoLisp
От переводчика: Продолжаем восполнять недостаток информации на русском языке об интереснейшем диалекте Lisp. Предыдущая статья: Разработка веб-приложений в PicoLispДомашняя страничка проекта: http://picolisp.com
Несколько недель назад моя жена попросила небольшое приложение — онлайновую базу данных для адресов и контактных данных членов семьи, родственников, друзей и так далее.Как правило, в PicoLisp база данных содержит объекты различных классов. Для их обработки в GUI должна быть возможность для поиска, создания и удаления объектов, редактирования их свойств.
Типичное PicoLisp-приложение реализует следующие возможности:
Пункт меню для каждого типа объекта или функции Диалоговое окно поиска, которое появляется при выборе пункта меню Поиск по нужным критериям в диалоговом окне Затем щелкните на найденный объект или на кнопку «Новый» для создания нового объекта Появится форма, где вы можете редактировать этот объект Форма имеет кнопку «Удалить», чтобы удалить этот объект Но в случае простой базы данных адресов это излишне. Есть только один класс объектов. К счастью, есть простой способ. Во-первых, нет необходимости для меню. Мы можем перейти непосредственно к адресам. Всё остальное можно обработать одним компонентом GUI, +QueryChart.Полный листинг в конце статьи.
Модель данных Определим класс «Person» (для целей данной статьи в слегка сокращенной форме) как: (class +Prs +Entity) (rel nm (+Sn +IdxFold +String)) # Name (rel adr (+IdxFold +String)) # Address (rel em (+String)) # E-Mail (rel tel (+String)) # Telephone (rel dob (+Date)) # Date of birth При необходимости класс можно легко расширить.Вместо отдельных свойств для улицы, индекса, города и т.д. у нас есть одно свойство в свободном формате для полного адреса. Мы определим два неуникальных индекса, один для имени пользователя и один для адреса. Индекс «name» поддерживает нечеткий поиск (с использованием алгоритма Soundex для похожих имен).
Функции графического интерфейса
У нас есть только одна GUI-функция под названием work. Она начинается со стандартных функций app (= установить сессию), action (= обработка событий формы) и html (= генерировать HTML-страницы), что типично для каждого приложения PicoLisp. Необязательная функция
(form NIL
(
+QueryChart используется во всех диалогах поиска. Он использует Pilog-запрос для поиска по заданному набору критериев, и отображает возможно неограниченное количество результатов, пока есть подходящие элементы, и пользователь продолжает нажимать кнопки прокрутки.
(gui 'query '(+QueryChart) 12 '(goal (quote @Nm (val> (: home nm)) @Adr (val> (: home adr)) (select (@@) ((nm +Prs @Nm) (adr +Prs @Adr)) (tolr @Nm @@ nm) (part @Adr @@ adr)))) Первый аргумент (здесь 12) дает начальное количество совпадений для заполнения таблицы. Второй аргумент — Pilog-запрос, который использует значения поисковых полей «Имя» и «Адрес» для нечеткого и частичного поиска. Смотрите http://software-lab.de/doc/select.html для подробной информации.Затем следуют три стандартных аргумента для класса +Chart
6 '((This) (list (: nm) (: adr) (: em) (: tel) (: dob))) '((L D) (cond (D (mapc '((K V) (put!> D K V)) '(nm adr em tel dob) L) D) ((car L) (new! '(+Prs) 'nm (car L)))))) , а именно: количество столбцов (здесь 6) и функции put и get.Класс +Chart вызывает эти функции всякий раз, когда что-то происходит в GUI. put-функция преобразует логическое содержание строки таблицы (здесь адрес объекта) в физическое отображение имени, адреса, email-а и т.д.:
'((This) (list (: nm) (: adr) (: em) (: tel) (: dob))) Аргумент This для put-функции — объект, и он разворачивается в список значений для строки таблицы.get-функция выполняет обратное действие, транслируя значения в строке в свойства объекта. Она принимает в L список значений из GUI (строки, числа, даты и т.п., введенные пользователем), а в D — адрес объекта в БД.
'((L D) Затем она проверяет, в выражении cond, существует ли объект D.Если да, она сохраняет значения из L в свойствах соответствующего объекта, обновляя таким образом БД по необходимости: (D (mapc '((K V) (put!> D K V)) '(nm adr em tel dob) L) D) Если объект не существует, но первая колонка таблицы содержит имя (которое пользователь только что ввёл), то создается новый объект в БД с этим именем: ((car L) (new! '(+Prs) 'nm (car L)))))) Вот и всё! Это вся логика, необходимая для создания и редактирования записей.+Chart или +QueryChart — внутренний объект, реализующий логику этого графического интерфейса.Теперь нам нужны физические компоненты для взаимодействия с пользователем.Поместим их в таблицу
(