XMLDB 新しいDDL関数の作成 (Dev docs)

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

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


重要: このページで紹介するすべての機能は、Moodle 2.0 以降 で使用するためのもので、ここではいくつかの新機能をサポートするために DB レイヤ を変更しました。もし、あなたが以前の Moodle バージョンの情報を必要とするならば、2.0 以前 のページをご覧ください。

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

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 オブジェクトは、XMLDBObject->getError() 関数で利用できるエラーに関する特別な情報を含みます) 。
  • 有効な場合、デバッグ情報を出力します。

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

はじめに

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

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

基本例

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

 
$field1 = new xmldb_field('id');
$field1->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, [null, null,] null, null); // [XMLDB_ENUM, null,] Moodle 2.x deprecated  
$field2 = new xmldb_field('name');
$field2->set_attributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, [null, null,] 'default name', 'id'); // [XMLDB_ENUM, null,] Moodle 2.x deprecated 
$field3 = new xmldb_field('course');
$field3->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, [null, null,] null, 'name'); //  [XMLDB_ENUM, null,] Moodle 2.x deprecated 
$field4 = new xmldb_field('type');
$field4->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, [XMLDB_ENUM, array('type1', 'type2', 'type3'),] 'type1', 'course'); //  [XMLDB_ENUM, null,] Moodle 2.x deprecated 
$field5 = new xmldb_field('summary');
$field5->set_attributes(XMLDB_TYPE_TEXT, 'medium', null, null, null, [null, null,] null, 'type'); //  [XMLDB_ENUM, null,] Moodle 2.x deprecated 
$key1 = new xmldb_key('primary');
$key1->set_attributes(XMLDB_KEY_PRIMARY, array('id'), null, null);
$key2 = new xmldb_key('foreignkey1');
$key2->set_attributes(XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id')); 
 
$index1 = new xmldb_index('type');
$index1->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('type'));
 
$table = new xmldb_table('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 = $dbman->create_table($table);

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

説明された例

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

$field1 = new xmldb_field('id');
$field1->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, [null, null,] null, null); //  [XMLDB_ENUM, null,] Moodle 2.x deprecated

最初の行では、"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 には length、NUMBERS には2つのカンマ区切りの数値(全長と小数点以下の桁数)、そして TEXTSとBINARIESはこのうちの1つ: "small", "medium", "big" を指定します。
  3. Unsigned: 数値フィールドが符号なしであるかどうかを指定するために、XMLDB_UNSIGNED 定数を使用します。符号付きの場合は、null を渡します。
  4. Not Null: フィールドが null でないかどうかを指定するために、XMLDB_NOTNULL 定数を使用します。null 可能であれば、null を渡します。
  5. Sequence: フィールドがシーケンス(または自動数値、自動インクリメント、その他呼び方は何でも)であるかどうかを指定するために、XMLDB_SEQUENCE 定数を使用することにします。そうでない場合は、null を渡します。
  6. Enum: フィールドが限られた数の値しか含まないかどうかを指定するために、XMLDB_ENUM 定数を使用します。そうでない場合は、null を渡します。 // Moodle 2.0 は非推奨
  7. Enum values: フィールドが XMLDB_ENUM として定義されている場合、このパラメータは、そのフィールドに可能なすべての値を含む 1 つの配列を持つことになります。そうでない場合は null です。 // Moodle 2.0 は非推奨
  8. Default value: フィールドに定義すべき意味のあるデフォルト値がある場合、このパラメータはそれを含みます。そうでない場合は、null です。
  9. After-field: もし、DB 内の他の正確なカラムの後にフィールドを作成することを強制したい場合、このパラメータでそうすることができます。指定しない場合、追加されたすべてのフィールドは最新のものの後に作成されるので、この例では全く定義できないことに注意してください。未定義の場合は、もう一度 null を使用することにします。

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

$field2 = new xmldb_field('name');
$field2->set_attributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, [null, null,] 'default name', 'id'); //  [XMLDB_ENUM, Enum values,] Moodle 2.x deprecated

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

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

$field3 = new xmldb_field('course');
$field3->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, [null, null,] null, 'name'); //  [XMLDB_ENUM, Enum values,] Moodle 2.x deprecated

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

もう1つのフィールド:

$field4 = new xmldb_field('type');
$field4->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, [XMLDB_ENUM, array('type1', 'type2', 'type3'),] 'type1', 'course'); //  [XMLDB_ENUM, Enum values,] Moodle 2.x deprecated

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

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

$field5 = new xmldb_field('summary');
$field5->set_attributes(XMLDB_TYPE_TEXT, 'medium', null, null, null, [null, null,] null, 'type');

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

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

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

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

$key1 = new xmldb_key('primary');
$key1->set_atrributes(XMLDB_KEY_PRIMARY, array('id'), null, null);

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

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

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

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

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

$key2 = new xmldb_key('foreignkey1');
$key2->set_attributes(XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));

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

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

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

$index1 = new xmldb_index('type');
$index1->set_attributes(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 xmldb_table('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 = $dbman->create_table($table);

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

ついに終わりです!!

縮小版 (推奨) 例

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

$table = new xmldb_table('my_first_xmldb_table');
 
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
$table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, 'default name');
$table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
$table->add_field('type', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, XMLDB_ENUM, array('type1', 'type2', 'type3'), 'type1');
$table->add_field('summary', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
 
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'), null, null);
$table->add_key('foreignkey1', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id')); 
 
$table->add_index('type', XMLDB_INDEX_NOTUNIQUE, array('type'));
 
$status = $dbman->create_table($table);

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

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

XMLDBエディタとの統合

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

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

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

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

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

関連項目

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