翻訳者から:数週間前、私の妻は小さなアプリケーションを要求しました-家族、親,、友人などの住所と連絡先の詳細のためのオンラインデータベース。
最も興味深いLisp方言に関するロシア語の情報不足を補い続けています。 前の記事: PicoLispでのWebアプリケーション開発
プロジェクトのホームページ: http : //picolisp.com
通常、PicoLispでは、データベースにさまざまなクラスのオブジェクトが含まれています。 GUIでそれらを処理するには、オブジェクトを検索、作成、削除、およびプロパティを編集する機能が必要です。
典型的なPicoLispアプリケーションは、次の機能を実装しています。
- オブジェクトまたは機能の各タイプのメニュー項目
- メニュー項目を選択すると表示される検索ダイアログボックス
- ダイアログボックスでの条件による検索
- 次に、見つかったオブジェクトまたは「新規」ボタンをクリックして、新しいオブジェクトを作成します
- このオブジェクトを編集できるフォームが表示されます。
- フォームには、このオブジェクトを削除するための削除ボタンがあります。
しかし、単純な住所データベースでは、これは不要です。 オブジェクトのクラスは1つだけです。 幸いなことに、簡単な方法があります。 まず、メニューは必要ありません。 住所に直接行くことができます。 他のすべては、単一の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
必要に応じて、クラスを簡単に拡張できます。
通り、郵便番号、都市などの個々のプロパティの代わりに 完全な住所に対して1つのプロパティが無料形式であります。 ユーザー名用とアドレス用の2つの一意でないインデックスを定義します。 「名前」インデックスは、ファジー検索をサポートしています(同様の名前にSoundexアルゴリズムを使用)。
GUI関数
work
というGUI関数は1つしかありません。 すべてのPicoLispアプリケーションに典型的な標準機能
app
(=セッションのセットアップ)、
action
(=フォームイベントの処理)、および
html
(= HTMLページの生成)で始まります。 オプションの
<ping>
関数はJavaScriptを使用してキープアライブイベントを生成します。
(de work () (app) (action (html 0 Ttl "@lib.css" NIL (<ping> 2)
次に、基本的なセキュリティ対策として、最初のフォームにパスワードフィールドが表示され、パスワード「mypass」がハードワイヤされています。 (ifn *Login (form NIL (gui 'pw '(+PwField) 20 ,"Password") (gui '(+Button) ,"login" '(ifn (= "mypass" (val> (: home pw))) (error ,"Permission denied") (on *Login) (url "!work") ) ) )
(実際のアプリケーションは(lib / adm.lライブラリを使用して)完全なユーザー/パスワード認証を使用します。ここでは簡潔にするために省略しました)
いずれの場合でも、グローバル変数* Loginを使用します。これは、パスワードが一致した場合に「ログイン」ボタンを押すことで設定されます。 この場合、2番目のメインフォームが表示されます。
(form NIL (<grid> "--." "Name" (gui 'nm '(+DbHint +TextField) '(nm +Prs) 20) (searchButton '(init> (: home query))) "Address" (gui 'adr '(+DbHint +TextField) '(adr +Prs) 20) (resetButton '(nm adr query)) )
「名前」と「住所」の2つの検索フィールドと、「検索」と「リセット」の2つのボタンが表示されます。 検索フィールドは、プレフィックスクラス+ DbHintを使用して、データベースに既に存在する一致する名前のドロップダウンリストを表示します。 [リセット]ボタンをクリックすると、すべてのフィールドがクリアされます。
次に、このアプリケーションのGUIの「中心」に進みましょう。
+QueryChart
クラスを使用して、レコードの検索とそれらの作成と編集の両方を行います。
+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)は、テーブルに入力する一致の初期数を示します。 2番目の引数はPilogリクエストで、ファジー検索および部分検索のために検索フィールド「Name」および「Address」の値を使用します。 詳細については、 http://software-lab.de/doc/select.htmlを参照してください。
次に、
+Chart
クラスの3つの標準引数があり
+Chart
6 '((This) (list (: nm) (: adr) (: em) (: tel) (: dob))) '((LD) (cond (D (mapc '((KV) (put!> DKV)) '(nm adr em tel dob) L ) D ) ((car L) (new! '(+Prs) 'nm (car L)) ) ) ) )
すなわち:列数(ここでは6)とput
および
get
関数。
GUIで何かが発生すると、
+Chart
クラスはこれらの関数を呼び出します。 put関数は、テーブル行の論理コンテンツ(ここではオブジェクトのアドレス)を名前、住所、電子メールなどの物理的な表示に変換します。
put関数への'((This) (list (: nm) (: adr) (: em) (: tel) (: dob)))
This
引数はオブジェクトであり、テーブル行の値のリストに展開されます。
get
関数は、文字列の値をオブジェクトのプロパティに変換することにより、反対のアクションを実行します。
L
はGUIからの値のリスト(ユーザーが入力した文字列、数値、日付など)が、
D
にはデータベース内のオブジェクト
D
アドレスが含まれます。
次に、'((LD)
cond
式でオブジェクト
D
が存在するかどうかをチェックし、存在する場合は、
L
の値を対応するオブジェクトのプロパティに保存し、必要に応じてデータベースを更新します。
(D (mapc '((KV) (put!> DKV)) '(nm adr em tel dob) L ) D )
オブジェクトが存在しないが、テーブルの最初の列に名前(ユーザーが入力したばかりの名前)が含まれている場合、この名前で新しいオブジェクトがデータベースに作成されます。 ((car L) (new! '(+Prs) 'nm (car L)) ) ) ) )
以上です! これが、レコードの作成と編集に必要なすべてのロジックです。
+Chart
または
+QueryChart
このグラフィカルインターフェイスのロジックを実装する内部オブジェクト
+QueryChart
ユーザーと対話するための物理コンポーネントが必要になります
+QueryChart
(<table> NIL (choTtl "Entries" '+Prs)
関連する見出し付き (quote (NIL "Name") (NIL "Address") (NIL "E-Mail") (NIL "Telephone") (NIL "Date of birth") )
続いて、テキスト、メール、電話のフィールドを含む12行 (do 12 (<row> NIL (gui 1 '(+TextField) 30) (gui 2 '(+TextField) 40) (gui 3 '(+MailField) 20) (gui 4 '(+TelField) 15) (gui 5 '(+DateField) 10) (gui 6 '(+DelRowButton) '(lose!> (curr)) '(text "Delete Entry @1?" (curr 'nm)) ) ) ) )
最後の列の[ +DelRowButton
]ボタンに注意し、データベースからレコードを削除するために使用できます。 ユーザーが本当にレコードを削除するかどうかを確認するダイアログが表示されます。 ただし、複数の行を削除する場合、次回ユーザーにプロンプトは表示されません。
そして最後に、4つの標準スクロールボタンが表示されます
(scroll 12) ) ) ) ) )
これらを使用すると、ページごとにテーブルのページ内容をスクロールできます。
初期化と起動
慣例により、PicoLispアプリケーションは2つの関数main
と
go
提供します.main関数は作業環境を初期化し、
go
はGUIイベントループを開始する必要があります。
(de main () (locale "UK") (pool "adr.db") ) (de go () (server 8080 "!work") )
locale
は、電話番号を
+TelField
フィールドを適切に処理するために主に必要です。 ローカライズ設定は
loc/
ディレクトリで提供できます。
以下のコードをファイル「minDbGui.l」にコピーするか、 http: //software-lab.de/minDbGui.lからダウンロードすると、この方法で実行できます。
デバッグモードの場合:$ pil minDbGui.l -main -go -wait
$ pil minDbGui.l -main -go +
プログラムソースコード
# 11jan15abu # (c) Software Lab. Alexander Burger (allowed () "!work" "@lib.css" ) (load "@lib/http.l" "@lib/xhtml.l" "@lib/form.l") (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 (de work () (app) (action (html 0 Ttl "@lib.css" NIL (<ping> 2) (ifn *Login (form NIL (gui 'pw '(+PwField) 20 ,"Password") (gui '(+Button) ,"login" '(ifn (= "mypass" (val> (: home pw))) (error ,"Permission denied") (on *Login) (url "!work") ) ) ) (form NIL (<grid> "--." "Name" (gui 'nm '(+DbHint +TextField) '(nm +Prs) 20) (searchButton '(init> (: home query))) "Address" (gui 'adr '(+DbHint +TextField) '(adr +Prs) 20) (resetButton '(nm adr query)) ) (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) ) ) ) 6 '((This) (list (: nm) (: adr) (: em) (: tel) (: dob))) '((LD) (cond (D (mapc '((KV) (put!> DKV)) '(nm adr em tel dob) L ) D ) ((car L) (new! '(+Prs) 'nm (car L)) ) ) ) ) (<table> NIL (choTtl "Entries" '+Prs) (quote (NIL "Name") (NIL "Address") (NIL "E-Mail") (NIL "Telephone") (NIL "Date of birth") ) (do 12 (<row> NIL (gui 1 '(+TextField) 30) (gui 2 '(+TextField) 40) (gui 3 '(+MailField) 20) (gui 4 '(+TelField) 15) (gui 5 '(+DateField) 10) (gui 6 '(+DelRowButton) '(lose!> (curr)) '(text "Delete Entry @1?" (curr 'nm)) ) ) ) ) (scroll 12) ) ) ) ) ) (de main () (locale "UK") (pool "adr.db") ) (de go () (server 8080 "!work") ) # vi:et:ts=3:sw=3