## 三つのテーブルの例

これ以降の例では、company データベース内の三つのテーブル company と department そして employee をすべて使用します。 これらの例では、これまでに説明してこなかった機能を説明します。 それは、包含関係ではない参照である employee_of_the_month です。

先に説明した company と department の例と同様、 これ以降の例でもデータグラフに対する一連の処理をすべて説明していきます。

例1 会社がひとつ、部署がひとつ、従業員が一人の例 - 作成

この例では、ひとつの会社にひとつの部署があり、 そこに従業員が一人だけ所属しているという構成になります。 この例では、まず最初に三つのテーブルの中身を削除していることに注意しましょう。 これにより、クエリの結果がどのようになるのかをはっきりさせています。

company、department および employee を作成した後で、company の employee_of_the_month プロパティを作成して新しい従業員を参照させているところに注目しましょう。 これは包含関係ではない参照なので、データグラフ内で employee オブジェクトを作成するまでは参照させることができません。 包含関係ではない参照の管理には注意が必要です。例えば、 ある employee が department から削除されたとすると、 employee_of_the_month プロパティを削除するか代入しなおさない限り、 データグラフを保存できなくなります。SDO データグラフの制約上、 包含関係でない参照の対象となっているオブジェクトは、 同時にいずれかの包含関係から到達可能である必要があります。

グラフの内容をデータベースに挿入する際の手順は、 company と department だけの時の例と似ています。しかし、 employee_of_the_month があるために少し複雑になります。 リレーショナル DAS は、包含関係で構成される木構造の順に、 オブジェクトを挿入していく必要があります。つまりまず company、 次に department、そして employee となります。なぜなら、 親データの自動生成された主キーの値を、子のデータに含めなければならないからです。 しかし、company を挿入した時点ではまだ「今月の従業員」 になる employee が挿入されておらず、その主キーの値がわかりません。 そこで、employee レコードが挿入されてその主キーが判明した時点で、 最後の処理が行われます。つまり company レコードを employee の主キーで更新します。

`<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';
/*************************************************************************************
* 3 つのテーブルを空にします。
*************************************************************************************/
$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();
$pdo_stmt = $dbh->prepare('DELETE FROM EMPLOYEE;');
$rows_affected = $pdo_stmt->execute();
/*************************************************************************************
* 小規模ながらも完全なる会社を作成します。
* 会社の名前は Acme。
* 部署はひとつだけで、Shoe。
* 従業員は一人だけで、Sue。
* 「今月の従業員」は Sue。
*************************************************************************************/
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_containment_metadata);
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
$root = $das -> createRootDataObject();
$acme = $root -> createDataObject('company');
$acme -> name = "Acme";
$shoe = $acme -> createDataObject('department');
$shoe -> name = 'Shoe';
$shoe -> location = 'A-block';
$sue = $shoe -> createDataObject('employee');
$sue -> name = 'Sue';
$acme -> employee_of_the_month = $sue;
$das -> applyChanges($dbh, $root);
echo "Acme のデータを、ひとつの部署と一人の従業員とともに書き戻します\n";
?>`

例2 会社がひとつ、部署がひとつ、従業員が一人の例 - 取得および更新

この場合、リレーショナル DAS に渡す SQL 文は、inner join を使用して三つのテーブルからのデータを取得します。ここでは、 これまでの例に出てこなかった新しい内容は特にありません。

新しい部署と従業員の追加によってグラフが更新され、 グラフ内の既存のオブジェクトの name プロパティに少し変更を加えます。 その後、それらの変更内容を書き戻します。リレーショナル DAS は、 データグラフへの追加・変更および削除の内容を適用します。

`<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';
/*************************************************************************************
* 会社のデータを取得し、いろいろ変更します。
* 会社、部署そして従業員の名前を変更します。
* 新しい部署と従業員を追加します。
* 「今月の従業員」を変更します。
*************************************************************************************/
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_containment_metadata);
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
$root = $das->executeQuery($dbh,
"select c.id, c.name, c.employee_of_the_month, d.id, d.name, e.id, e.name " .
"from company c, department d, employee e " .
"where e.dept_id = d.id and d.co_id = c.id and c.name='Acme'",
array('company.id','company.name','company.employee_of_the_month',
'department.id','department.name','employee.id','employee.name'));
$acme = $root['company'][0];
$shoe = $acme->department[0];
$sue = $shoe -> employee[0];
$it = $acme->createDataObject('department');
$it->name = 'IT';
$it->location = 'G-block';
$billy = $it->createDataObject('employee');
$billy->name = 'Billy';
$acme->name = 'MegaCorp';
$shoe->name = 'Footwear';
$sue->name = 'Susan';
$acme->employee_of_the_month = $billy;
$das -> applyChanges($dbh, $root);
echo "会社のデータを、追加した部署や従業員そして変更後の名前 (Megacorp/Footwear/Susan) などどともに書き戻します\n";
?>`

例3 会社がひとつ、部署がふたつ、従業員が二人の例 - 取得および削除

company は、5 つのデータオブジェクトを含むデータグラフとして取得されます。 5 つとは、すなわちその会社、ふたつの部署、そして二人の従業員です。 company オブジェクトをグラフから削除すると、 その配下にあるすべてのオブジェクトがグラフから削除されます。 つまり、5 つの SQL DELETE 文が作成されて実行されます。 取得したすべてのフィールドの内容が WHERE 句に指定されるので、 別のプロセスがデータベースの内容を変更していた場合にはそれを検出することができます。

`<?php
require_once 'SDO/DAS/Relational.php';
require_once 'company_metadata.inc.php';
/*************************************************************************************
* もう一度読み込み、それを削除します。
* 一部を削除し、変更を適用し、同じグラフで作業を続けることもできますが、
* 破綻しないように注意が必要です。「今月の従業員」になっている従業員を削除するには、
* まずその割り当てを変更しておかなければなりません。安全のため、ここでは
* 会社ごとすべて削除しています。
*************************************************************************************/
$das = new SDO_DAS_Relational ($database_metadata,'company',$SDO_containment_metadata);
$dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
$root = $das->executeQuery($dbh,
"select c.id, c.name, c.employee_of_the_month, d.id, d.name, e.id, e.name " .
"from company c, department d, employee e " .
"where e.dept_id = d.id and d.co_id = c.id and c.name='MegaCorp';",
array('company.id','company.name','company.employee_of_the_month',
'department.id','department.name','employee.id','employee.name'));
$megacorp = $root['company'][0];
unset($root['company']);
$das -> applyChanges($dbh, $root);
echo "会社と部署と従業員を一度に削除しました。\n";
?>`