XMLDB 新しいDDL関数の作成 (Dev docs) - 2.0 以前

提供:MoodleDocs
移動先:案内検索

XMLDB ドキュメンテーション > ロードマップ > XMLDB 新しいDDL関数の作成


ジャスティフィケーション

XMLDB の構造 がうまく定義され、それを使ってどんな DB モデルでも抽象化できるようになったら、今度はその XML 構造から提供される情報をもとに、必要な DB オブジェクトを生成する関数群を構築することにしましょう。これらの関数はすべて XMLB オブジェクト (XMLDBTable, XMLDBField, XMLDBKey, XMLDBIndex) を使用し、抽象度を保つようにします。

これらの機能によって供給される目的は、以下のとおりです:

  • インストール プロセスで使用され、古い *.sql の使用に取って代わり、必要なすべての DB オブジェクトを作成します。
  • アップグレード プロセスで、新しい upgrade.php スクリプトで、すべての DB オブジェクトを処理するために使用されます。

当初、XMLDBオブジェクトをDDL関数で使用するか、XMLDBスキーマから完全に独立した新しい関数を大量に作成するかは完全に決まっていませんでしたが、最終的に、以前に作成したオブジェクトを使用することにしました。主な理由は:

  • テーブルやフィールドなどを表すオブジェクトがある場合、同じ種類のオブジェクトをパラメータとして必要とする新しい関数を作って、それを使わないというのはあまり意味がないことです。
  • XMLDB オブジェクトに変更があれば、DDL 関数ですぐに利用できるようになります(新しいカラムタイプが1つ追加されます...)。
  • SQL コードの生成はすべて XMLDB クラス自身が担当するので、DDL 関数内のコードは非常にシンプルになります。
  • XMLDB オブジェクトを利用することで、XMLDB エディタ(XMLDB の構造を簡単に編集するツール)を改良し、upgrade.php スクリプトで使用する必要な PHP コードを自動的に生成することができるようになりました。オブジェクト(テーブル/フィールド/インデックス/キー)と実行するアクション(作成/削除/名前変更/変更)を選択するだけで、なんと!アップグレードスクリプトに貼り付けるすべての PHP コードを取得することができます。(近日公開) ;-)

唯一の欠点は、XMLDB オブジェクトの作成と定義のコードをすべて含む必要があるため、アップグレードのコードが少し長くなることです。しかし、逆に言えば、読みやすいコードになるわけです。

実装

基本概念

すべての機能:

  • XMLDB オブジェクト (修正されるもの) をパラメータとして受け取ります。
  • DB に対して SQL コマンドを実行する前に、可能な限りのチェックを行います。
  • 成功/エラー時 に true/false を返す。 (XMLDB オブジェクトは、XMLDB Object->getError() 関数で利用可能なエラーに関する追加情報を含みます。).
  • 有効な場合、デバッグ情報を出力します。

XMLDB オブジェクトの取り扱い

導入

DDL 関数自体を呼び出す前に、適切な XMLDB オブジェクトを適切に作成し、関数が作業を行えるようにするために必要な情報をすべて含んでいる必要があります。あらゆる DDL 操作の基本的なコード構造はこうであるべきです:

  1. プログラムによる XMLDB オブジェクトの作成。
  2. DDL 関数の呼び出し。
  3. エラーのチェック。

基本例

この手順の簡単な例として、次のような PHP の行があります。これは、主キー、外部キー、インデックスをひとつずつ持つ単純なテーブルを作成するために使用します:

$field1 = new XMLDBField('id');
$field1->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null, null);
$field2 = new XMLDBField('name');
$field2->setAttributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, 'default name', 'id');
$field3 = new XMLDBField('course');
$field3->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null, 'name');
$field4 = new XMLDBField('type');
$field4->setAttributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, XMLDB_ENUM, array('type1', 'type2', 'type3'), 'type1', 'course');
$field5 = new XMLDBField('summary');
$field5->setAttributes(XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null, 'type');

$key1 = newXMLDBKey('primary');
$key1->setAttributes(XMLDB_KEY_PRIMARY, array('id'), null, null);
$key2 = newXMLDBKey('foreignkey1');
$key2->setAttributes(XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id')); 

$index1 = newXMLDBIndex('type');
$index1->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('type'));

$table = new XMLDBTable('my_first_xmldb_table');
$table->addField($field1);
$table->addField($field2);
$table->addField($field3);
$table->addField($field4);
$table->addField($field5);

$table->addKey($key1);
$table->addKey($key2);

$table->addIndex($index1);

$status = create_table($table);

まず、慌てないことです!上記のコードは簡単に、正確には10行に減らすことができますが、ある程度詳しく説明するために、長いバージョンをここに掲載します。 ;-) また、XMLDB オブジェクトの使用に関する今後の機能の一つとして、XMLDB エディタがこれらの PHP コードを全て自動生成してくれる ことも忘れてはいけません。

説明された例

まず、最初の2行から見ていきましょう:

$field1 = new XMLDBField('id');
$field1->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null, null);

最初の行では、"id" という新しいフィールドを作っています(これはテーブルのカラムの名前になるので、XMLDB 命名規則コーディングガイドライン に従うことを忘れないでください)。

2行目では、単純な関数呼び出しで、フィールドのすべての属性を定義しています。パラメータの一覧です:

  1. Column Type: これらのうち: XMLDB_TYPE_INTEGER, XMLDB_TYPE_NUMBER, XMLDB_TYPE_CHAR, XMLDB_TYPE_TEXT, XMLDB_TYPE_BINARY のいずれかです。XMLDB の内部では他のカラムタイプもサポートしていますが、それはいくつかの特別なテーブルとの互換性のためだけであることに注意してください。Moodle は上記のリストから外れたものを使用するべきではありません。
  2. Column precision: INTEGERS と CHARS は長さ、NUMBERS はカンマで区切られた2つの数値(全長と小数点以下の桁数)、そしてこのうちの1つです: "small", "medium", "big", TEXTS および BINARIES の両方。
  3. Unsigned: 数値フィールドが符号なしであるかどうかを指定するために、XMLDB_UNSIGNED 定数を使用します。符号付きの場合は、null を渡します。
  4. Not Null: フィールドが null でないかどうかを指定するために、XMLDB_NOTNULL 定数を使用します。null が可能な場合、null を渡します。
  5. Sequence: フィールドがシーケンス(または自動数値入力、または自動インクリメント、またはあなたがそれを呼ぶもの)であるかどうかを指定するために、XMLDB_SEQUENCE 定数を使用します。そうでない場合は、null を渡します。
  6. Enum: フィールドが限られた数の値しか含まないかどうかを指定するために、XMLDB_ENUM 定数を使用します。そうでない場合は、null を渡します。
  7. Enum values: フィールドが XMLDB_ENUM として定義されている場合、このパラメータは、そのフィールドに可能なすべての値を含む1つの配列を持つことになります。そうでない場合は null です。
  8. Default value: フィールドに定義すべき意味のあるデフォルト値がある場合、このパラメータはそれを含みます。そうでない場合は、null です。
  9. After-field: もし、DB 内の他の正確なカラムの後にフィールドを作成することを強制したい場合、このパラメータでそうすることができます。指定しない場合、追加されたすべてのフィールドは最新のものの後に作成されるため、この例では全く定義できないことに注意してください。未定義の場合はもう一度 null を使用します。

つまり、上記のコードでは、"id" という名前の1つのフィールドを作成しています。このフィールドは、10桁の整数で、null ではなく、自動数字になります。次のフィールドを見てみましょう:

$field2 = new XMLDBField('name');
$field2->setAttributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, 'default name', 'id');

ここでは、"name" という名前の新しいフィールドを1つ作成しています。これは、最大長 255cc の1文字で、null ではなく、デフォルト値("default name")で、"id" フィールドの後に作成されます(繰り返しますが、表を作成するのに、この順序はまったく役に立たず、表にフィールドを追加した順序が使われることに注意してください)。

次に検証してみましょう:

$field3 = new XMLDBField('course');
$field3->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null, 'name');

別の新しいフィールド、名前は "course"、最大長は10、符号なし、null ではない整数値です (上の行で述べたように、after-field の情報を定義するために 'name' 値を忘れています)。

もう1つのフィールド:

$field4 = new XMLDBField('type');
$field4->setAttributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, XMLDB_ENUM, array('type1', 'type2', 'type3'), 'type1', 'course');

このフィールドは "type" と呼ばれ、char(20) で null ではなく、3つの値 ("type1", "type2", "type3") を持ち、そのデフォルト値は "type1" となります。

そして、この例では最後のフィールドです:

$field5 = new XMLDBField('summary');
$field5->setAttributes(XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null, 'type');

それは、"summary" というフィールド名で、長さが "medium" の text タイプになります。

また、これらの "null" パラメータをすべて指定することは必須ではなく、右から順に、安全に避けることができることに注意してください。したがって、最後に見たフィールドは、(もう一度、after-field パラメータを無視すれば)可能性があります:

$field5->setAttributes(XMLDB_TYPE_TEXT, 'medium');

では、キーの作成について解析してみましょう。この例で最初に指定するキーは:

$key1 = newXMLDBKey('primary');
$key1->setAttributes(XMLDB_KEY_PRIMARY, array('id'), null, null);

最初の行で、"primary" という名前のインデックスを作成します。前のコードで指定したフィールド名はDBのフィールド名になるので重要ですが、ここで指定した名前は全く重要ではありません。主にXMLDBのキーとインデックスの命名規則のため、作成されるキーとインデックスはその規則に従って自動的に命名されます。とにかく、XMLDBのファイルでは、主キーを "primary" と呼び、キー/インデックスのフィールド名を "-" で区切って連結し、正式な名前としています。しかし、ここではそれは重要ではありません。

2行目で完全にキーを定義しています。属性は:

  1. Key Type: これらのうちの1つ: XMLDB_KEY_PRIMARY, XMLDB_KEY_UNIQUE, XMLDB_KEY_FOREIGN は、リレーショナルDBモデルの基本的な制約タイプです。重要なのは、上記のすべてのキーには自動的に1つのインデックスが作成されるので、キーを定義するときに、同じフィールドを持つインデックスを定義する必要は全くないということです。XMLDB がやってくれます。しかし、私たちは、XMLDB の初期から定義されているこれらの関係をすべて持っていたいのです。そうすることで、純粋なリレーショナルモデルに素早く移行することができるようになります。
  2. List of fields: キー (およびその下のインデックス) の一部となるフィールドの名前を含む配列です。
  3. Reference table: 外部キーの場合のみ、前のパラメータで定義されたフィールドが指し示すテーブルです。
  4. Reference fields: 外部キーの場合のみ、参照テーブルのフィールドのリストと自テーブルのフィールドのリストが一致する必要があります。これらの "reference fields" は、参照テーブルの主キーまたはユニークキーとして定義されなければならないことに注意してください。関係性のルールというものです。そのため、この条件を完全に満たさないフィールドを指すことは避けてください!

これらの情報から、"id" というフィールドで1つの主キーを作成することがわかりました。XMLDB はそのキーに正しい名前を設定することを忘れないでください。

例の2番目のインデックスには、こう書かれています:

$key2 = newXMLDBKey('foreignkey1');
$key2->setAttributes(XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id')); 

ここでは、"course" テーブルの "id" フィールドを指す "course" フィールドを持つ、外部キータイプのキーをもう1つ作成しています。もう一度言いますが、名前はまったく重要ではありません。

そして、最後にインデックスにたどり着きます。以前に定義されたすべてのキーは、指定されたフィールドを持つ 1 つの基になるインデックスを生成することを忘れないでください。したがって、このセクションでは、SQL ステートメントで頻繁に使用されるフィールドの他の組み合わせを定義するだけで済みます。正しいインデックスを提供することで、速度が大幅に向上します。しかし、それらは正しくなければなりません。何も知らずに "何でもかんでもインデックスを付ける" のは絶対に間違っています。忘れないようにしましょう!

この例では、次のようなコードになっています:

$index1 = newXMLDBIndex('type');
$index1->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('type'));

最初の行では、新しいインデックスオブジェクトを作成しています。 ここで指定した名前は、RDBMS におけるインデックスの名前ではないことに注意してください。XMLDBのキーおよびインデックスの命名が自動的にそれを定義します。

2行目では、こう指定しています:

  1. Index Type: 前のパラメータで定義されたフィールドのリストがタプルの重複を許すかどうかによって、XMLDB_INDEX_NOTUNIQUE (デフォルトでは null とほぼ同じ) または XMLDB_INDEX_UNIQUE にすることができます。
  2. List of fields: インデックスの一部となるフィールドの名前を含む配列です。

そこで、この例では、"type" というフィールドを持つ一意でないインデックスを1つ作成することにします。

これで、1つのテーブル構造に適合する個々のオブジェクトをすべて見ることができました。さて、これらのオブジェクトをすべて新しいテーブルに移動させるので、コードは次のようになります:

$table = new XMLDBTable('my_first_xmldb_table');
$table->addField($field1);
$table->addField($field2);
$table->addField($field3);
$table->addField($field4);
$table->addField($field5);

$table->addKey($key1);
$table->addKey($key2);

$table->addIndex($index1);

この行では、"my_first_xmldb_table" という名前の新しいテーブルを1つ作成するだけです。その名前はXMLDBの命名規則コーディングガイドライン に従わなければなりません。そして、以前に定義したすべてのフィールド、キー、インデックスがテーブルに追加されます。ポイントです。

そして、コードの最終行は:

$status = create_table($table);

この行で、前の行で定義したすべての仕様で指定されたすべてのフィールド/キー/インデックスを持つ DB テーブルを、正しい接頭辞、適切なオブジェクト名、異なる RDBMS ごとの特殊性で作成することになります。この関数呼び出しは、必要なSQLコマンドの実行が可か否かに応じて、true/false を返します。

ついに、終わりです!!

縮小例

上の例のすべての行は、XMLDBField、XMLDBKey、XMLDBIndex、XMLDBTable の各構造体を PHP コードから作成する方法を説明するのに非常に適していますが、読みやすさと長さの点では少しひどいと認識する必要があります。そこで、テーブルの作成には、従来のものを完全に置き換えた、次のようなコードを使用します:

$table = new XMLDBTable('my_first_xmldb_table');

$table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
$table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, 'default name');
$table->addFieldInfo('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
$table->addFieldInfo('type', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, XMLDB_ENUM, array('type1', 'type2', 'type3'), 'type1');
$table->addFieldInfo('summary', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);

$table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'), null, null);
$table->addKeyInfo('foreignkey1', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id')); 

$table->addIndexInfo('type', XMLDB_INDEX_NOTUNIQUE, array('type'));

$status = create_table($table);

良くなったのではないでしょうか? ;-)

前の完全な例でのドキュメントはすべて、ここでも100%有効です。この構文を使う場合、フィールドがひとつ増えることに注意しましょう。まさに 最初のもの で、追加するフィールド/キー/インデックスの名前を指定しなければなりません。それ以外はまったく同じです!

XMLDBエディタとの統合

これで、新しい XMLDB スキーマのもとで PHP を使ってテーブルを作成する方法について、もう少し詳しく知ることができたでしょう。その過程で、フィールド、キー、インデックスの作り方、さらに全体についての余分な概念を見たことになるので、それを知ることは本当に重要でした。

また、テーブルの作成は、新しい DDL 関数の中で最も難しい操作です(PHP が生成する点では、その差はありますが)。その他、名前の変更、ドロップ、変更など、本当に簡単に操作できるようになります。PHP の世代で少し手助けをしてみると、XMLDB エディタを使って DB 構造を設計・作成すれば、さまざまな DDL アクションを実行するために必要なすべてのコードを自動的に取得することができるようになります。

変更したいテーブル/フィールド/キー/インデックスに移動し、必要な変更を行った後、"PHP Code" リンクを押すと、利用可能なすべての (実質的な) オプションのある新しいページが表示されます。選択するだけで、必要な PHP が瞬時に表示されます。

このようなコードは、アップグレードスクリプトで直接使用することができ、(あちこちの小さな部分を修正することで) DB の使用感を向上させ、エラーのリスクを大幅に軽減することができます。

また、このようなユーティリティを使用することで、オンライン家庭教師のように PHP コードの仕組みをより深く理解することができますので、非常におすすめです。お楽しみに!

関連項目

  • DDL 関数: DB オブジェクトを変更するために利用可能な関数に関する最新のドキュメントにアクセスすることができます。
  • XMLの構造: 1つの中立的な言語を使ってすべての DB オブジェクトを記述するために使用される内部 XML 構造についてもう少し詳しく知ることができます。
  • 作成する関数のリスト: ゼロから作成する関数のリストです。進捗状況やその状態を追うために使用します。