これ以降の例では、company データベース内のふたつのテーブル company と department を使用します。これらの例は、 リレーショナル DAS の機能をより活用するためのものです。
この一連の例では、まず company および department を作成し、 それを取得し、更新して最後に削除します。複数のオブジェクトからなる データグラフの動きについて、ここで説明します。 この例では、まず最初に company および department のふたつのテーブルの中身を削除していることに注意しましょう。 これにより、クエリの結果がどのようになるのかをはっきりさせています。
これらの例については、リレーショナル DAS パッケージの Scenarios ディレクトリ内にあるスクリプト 1cd-CRUD にまとめてあります。
例1 会社がひとつ、部署がひとつの例 - 作成
先の、company データオブジェクトをひとつだけ作成する例で示したように、 リレーショナル DAS を作成した後でまず行うことは createRootDataObject() をコールして空のデータグラフを持つ特別なルートオブジェクトを取得することです。 その後、このルートオブジェクトの子要素として company オブジェクトを作成し、company オブジェクトの子要素として department オブジェクトを作成します。
変更内容を適用する際には、包含関係を定義する外部キー制約を満たすため、 リレーショナルが特別な処理を行います。特に、 自動生成される主キーが含まれれる場合の処理が大切です。 この例では、company テーブルで自動生成された主キー id と department テーブルのカラム co_id の関係を指定しなければなりません。 company および department に最初にデータを挿入する際、 リレーショナル DAS はまず最初に company に行を挿入してから PDO の getLastInsertId() メソッドで 自動生成された主キーを取得し、department に行を挿入する際の co_id カラムにその値を指定しなければなりません。
<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';
/*************************************************************************************
* ふたつのテーブルを空にします。
*************************************************************************************/
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
$pdo_stmt = $dbh->prepare('DELETE FROM COMPANY;');
$rows_affected = $pdo_stmt->execute();
$pdo_stmt = $dbh->prepare('DELETE FROM DEPARTMENT;');
$rows_affected = $pdo_stmt->execute();
/**************************************************************
* Acme という名前の会社、Shoe という名前の部署を作成します。
***************************************************************/
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_containment_metadata);
$root = $das -> createRootDataObject();
$acme = $root -> createDataObject('company');
$acme -> name = "Acme";
$shoe = $acme->createDataObject('department');
$shoe->name = 'Shoe';
$das -> applyChanges($dbh, $root);
?>
例2 会社がひとつ、部署がひとつの例 - 取得および更新
この場合、executeQuery() に渡す SQL クエリは inner join を使用して company テーブルと department テーブルを連結します。company テーブルと department テーブルの両方の主キーがクエリに含まれている必要があります。 結果セットは正規化されたデータグラフ形式になります。 executeQuery() をコールする際に、 三番目の引数としてカラム指定子を渡していることに注意しましょう。 これにより、どのカラムが結果セットのどこに対応するのかを リレーショナル DAS に教えています。
クエリ内でカラム co_id が使用されていますが、 これは結果セットでは必要ないことに注意しましょう。 データグラフを作成する際にリレーショナル DAS がどのような処理をするのかを理解するには、 結果セットがどのようになるのかを図示してみるといいでしょう。 データベース内のデータは正規化されており、 複数の部署データが外部キーを通じてひとつの会社データを参照するようになっていますが、 結果セット内のデータは正規化されていません。つまり、 もしひとつの会社に複数の部署があるのなら、 会社のデータはその行の数だけ繰り返されます。 リレーショナル DAS は、この手順を逆転させて 結果セットを正規化されたデータグラフに戻し、company オブジェクトがひとつだけになるようにしなければなりません。
この例では、リレーショナル DAS が結果セットとカラム指定子を調べ、 company テーブルと department テーブルからデータを取得し、 それぞれの主キーを検索し、各 department とその親となる company を関連付けます。該当する company をまだ取得していない場合は (これは主キーで判断します)、新しい company オブジェクトを作成して department オブジェクトをその下に関連付けます。 すでに company オブジェクトが存在する場合は、 その下に department オブジェクトを作成するだけです。
この方法によって、リレーショナル DAS は複数の会社と複数の部署が含まれるデータを 取得して再度正規化します。
<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';
/**************************************************************
* 会社、そして部署 Shoe を取得します。
* それから Shoe を削除して IT を追加します。
***************************************************************/
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_containment_metadata);
$root = $das->executeQuery($dbh,
'select c.id, c.name, d.id, d.name from company c, department d where d.co_id = c.id',
array('company.id','company.name','department.id','department.name'));
$acme = $root['company'][0]; // 最初の会社を取得します - 'Acme' となるでしょう。
$shoe = $acme['department'][0]; // その下の最初の部署を取得します - 'Shoe' となるでしょう。
unset($acme['department'][0]);
$it = $acme->createDataObject('department');
$it->name = 'IT';
$das -> applyChanges($dbh, $root);
?>
例3 会社がひとつ、部署がふたつの例 - 取得および削除
この例では、会社と部署を取得し、それから削除します。 それぞれを個別に削除する必要はありません (そうすることも可能です)。 データグラフから company オブジェクトを削除すると、 その下に関連付けられている department も削除されます。
company オブジェクトを削除する際に、PHP の unset をコールしていることに注意しましょう。unset は、 それを保持しているプロパティに対して行わなければなりません。 この場合は、ルートオブジェクトの company プロパティに対して行います。 つまり、このようにしなければなりません。
<?php
unset($root['company'][0]);
?>
<?php
unset($acme); // 間違い
?>
<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';
/**************************************************************
* 会社、そして部署 IT を取得します。
* 会社全体を削除します。
**************************************************************/
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_containment_metadata);
$root = $das->executeQuery($dbh,
'select c.id, c.name, d.id, d.name from company c, department d where d.co_id = c.id',
array('company.id','company.name','department.id','department.name'));
$acme = $root['company'][0];
$it = $acme['department'][0];
unset($root['company'][0]);
$das -> applyChanges($dbh, $root);
?>