PicoLisp上の最小限のDB / GUIアプリケーション

翻訳者から:
最も興味深い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関数は、テーブル行の論理コンテンツ(ここではオブジェクトのアドレス)を名前、住所、電子メールなどの物理的な表示に変換します。
  '((This) (list (: nm) (: adr) (: em) (: tel) (: dob))) 
put関数への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つの関数maingo提供します.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 

Source: https://habr.com/ru/post/J247965/


All Articles