特になし。
The Database
おいおい、テーブルから始めるんですか。。。
- クラスtable は rowsとschemaというslotsを持つ。rowsは関数make-rowsによって初期化される。
- rowsは a vectorに格納されるようにする。
- make-rowsはmake-arrayの単純なラッパーになる。
- クラスcolumnはschemaの構成要素である。
- クラスcolumnは次のslotsからなる。
- name
- equality-predicate
- comparator
- default-value 初期値はnil
- value-normalizer ここのinitformに何故このようなlambdaを置いているのか理解できない。(↓で解決)
- name
Defining a Schema
- equality-predicateとcomparatorの組は、型を定義することと同義である。
- column objectsをmake-instanceで直に作るより、型を指定して生成するインターフェイスの方が便利。
- ここでは総称関数を使う方法をとる。
(defgeneric make-column (name type &optional default-value)) - stringとnumberについてeql-specialized methodを定義する。
- stringのvalue-normalizerは#'not-nullableという関数。nilだとsignalを上げる。
- numberはvalue-normalizerは指定しない。すなわちinitformのもの。
- interned-string向けにはまずcolumnのサブクラスを定義する。
(defclass interned-values-column (column) ...) - これにはinterned-valuesというa slotを追加する。これはhash。
- value-normalizerで、intern処理をする。関数名はintern-for-column。
- interned-string用のmake-columnも定義。
- これで、make-columnは、string,number,interned-stringについて定義できた。
- make-schemaを次のように定義。
(defun make-schema (spec)
(mapcar #'(lambda (column-spec) (apply #'make-column column-spec)) spec)) - specの例は次のとおり。
(defparameter *mp3-schema*
(make-schema
'((:file string)
(:genre interned-string "Unknown")
(:artist interned-string "Unknown")
(:album interned-string "Unknown")
(:song string)
(:track number 0)
(:year number 0)
(:id3-size number))))
Inserting Values
- insert-rowはtableにa rowを挿入する関数である。
- normalize-rowというヘルパー関数を作る。
- names-and-valuesという引数を用意する。これはa plist。
- normalize-for-columnというヘルパー関数を用意する。これはcolumn毎のvalue-normalizerを呼ぶ。
- 関数file-rowは、MP3ファイルからID3情報をread-id3で抽出した上で、それをrowとして*mp3s*に格納するためのplistを作成する。
Querying the Database
うう、別にRDBを作りたくはないのだが。。。どこに連れていく気なんだ。。。
Matching Functions
Getting at the Results
Other Database Operations
特になし。
チュートリアルとしてはいろいろ参考になったのですが、作っているのがRDBなので、それは既存のRDBを使えばいいんじゃないの、とついつい思ってしまいます。バイナリデータのときとかは、あまりそう思わなかったのですが、なんででしょうね。
0 件のコメント:
コメントを投稿