データモデルオブジェクト
ORDA は、下地であるデータベースストラクチャーへの自動マッピングに基づいた技術です。 ORDA は、エンティティやエンティティセレクションオブジェクトを介してデータへのアクセスも提供します。 結果的に ORDA は、データモデルオブジェクト一式の形でデータベース全体を公開します。
ストラクチャーマッピング
When you call a datastore using the ds
or the Open datastore
command, 4D automatically references tables and fields of the corresponding 4D structure as properties of the returned datastore object:
- テーブルはデータクラスへとマップされます。
- フィールドはストレージ属性へとマップされます。
- リレーションはリレーション属性へとマップされます。ストラクチャーエディター内で定義されたリレーション名はリレーション属性名として使用されます。
変換のルール
変換の際には以下のルールが適用されます:
- テーブル、フィールド、そしてリレーション名はオブジェクトプロパティ名へとマップされます。 それらの名前が標準のオブジェクト命名規則に則っているようにしてください (識別子の命名規則 参照)。
- データストアは単一のプライマリーキーを持つテーブルのみを参照します。 以下のテーブルは参照されません:
- プライマリーキーがないテーブル
- 複合プライマリーキーを持つテーブル
- BLOBフィールドは、BLOB オブジェクト 型の属性として利用可能です。
ORDA のデータストアマッピングでは、次のものは考慮されません:
- テーブルあるいはフィールドの "非表示" オプション
SET TABLE TITLES
あるいはSET FIELD TITLES
を通して定義されたバーチャルストラクチャー- リレーションの "手動" あるいは "自動" プロパティ
リモートデータストアの利用
Open datastore
コマンドまたは REST リクエスト によってリモートデータストアにアクセスする場合、RESTリソースとして公開 プロパティが設定されているテーブルとフィールドのみ利用可能です。
このプロパティは、データストアにデータクラスおよび属性として公開したい各テーブルおよびフィールドについて 4D ストラクチャーのレベルで設定する必要があります:
データモデルのアップデート
データベースストラクチャーレベルで変更がおこなわれると、カレントの ORDA モデルレイヤーは無効化されます。 これらの変更には、以下のものが含まれます:
- テーブル、フィールド、リレーションの追加または削除
- テーブル、フィールド、リレーションの名称変更
- フィールドの核となるプロパティ (型、重複不可、インデックス、自動インクリメント、null値サポートなど) の変更
カレントの ORDA モデルレイヤーが無効化されると、その後 4D または 4D Server のローカルの ds
データストアを呼び出した時にモデルレイヤーが自動的に再読み込みされ、更新されます。 ただし、エンティティやエンティティセレクションなど、ORDA オブジェクトへの既存の参照は、再生成されるまではそれらが作成されたときのモデルを使用し続けるという点に注意してください。
また、アップデートされた ORDA モデルレイヤーは、以下のコンテキストにおいては自動的には利用可能にはなりません:
- 4D Server に接続したリモートの 4D -- リモートのアプリケーションはサーバーに再接続する必要があります
Open datastore
または REST 呼び出し を使用して開かれたリモートデータストア -- 新しいセッションを開く必要があります
オブジェクトの定義
データストア
データストアは、データベースへのインターフェースオブジェクトです。 データベース全体を反映したものをオブジェクトとしてビルドします。 データストアは モデル と データ から構成されています:
- モデルにはデータストアを構成するすべてのデータクラスが格納され、その詳細な情報も含まれます。 これはその下地にあるデータベース自体からは独立した存在です。
- データとは、そのモデル内で使用・保存される情報を指します。 たとえば、従業員の名前、住所、生年月日などはデータストア内で扱うことができるデータに含まれます。
コード内で扱うにあたっては、データストアはオブジェクトであり、公開されているすべての データクラス をプロパティとして持ちます。
4D では次のデータストアを扱うことができます:
- カレント 4D データベースに基づいた、ローカルデータストア。これは、
ds
コマンドで返されるメインデータストアです。 - リモートデータベースによって REST リソースとして公開された、一つ以上のリモートデータストア。これらは、
Open datastore
コマンドで返されます。
データストアは単一の、ローカルあるいはリモートのデータベースを参照します。
データストアオブジェクト自身は、オブジェクトとしてコピーすることはできません:
$mydatastore:=OB Copy(ds) // null を返します
しかしながらデータストアプロパティは取得可能です:
ARRAY TEXT($prop;0)
OB GET PROPERTY NAMES(ds;$prop)
// $prop にはすべてのデータクラスの名前が格納されます
メイン (デフォルト) のデータストアは ds
コマンドを通して常に利用可能です。Open datastore
コマンドを使えば、あらゆるリモートデータストアを参照することができます。
データクラス
データクラスとは、テーブルに相当するものです。 オブジェクトモデルとして使用され、リレーショナル属性 (データクラス間のリレーションに基づいてビルドされた属性) を含めてすべてのフィールドを属性として参照します。 リレーショナル属性はクエリにおいて通常の属性のように使用することができます。
4D プロジェクト内のすべてのデータクラスは、ds
データストアのプロパティとして利用可能です。 Open datastore
コマンドまたは REST リクエスト によってアクセスするリモートデータストアの場合、データストアのデータクラスとして公開したい各テーブルについて 4D ストラクチャーのレベルで RESTリソースとして公開 プロパティを設定する必要があります。
たとえば、4D ストラクチャー内の以下のテーブルについて考えます。
Company
テーブルは ds
データストア内のデータクラスとして自動的に利用可能です。 以下のように書くことができます:
var $compClass : cs.Company // Company クラスのオブジェクト変数として $compClass を宣言します
$compClass:=ds.Company // Company データクラスへの参照を $compClass に代入します
データクラスオブジェクトは以下のものを格納することができます:
- 属性
- リレーション属性
データクラスは実際のデータベースの概略を提供し、概念的なデータモデルの管理を可能にします。 データクラスはデータストアをクエリする唯一の方法です。 クエリは単一のデータクラスを通して実行されます。 クエリはデータクラスの属性およびリレーション属性名に基づいてビルドされます。 リレーション属性は、一つのクエリ内で複数のリンクされたテーブルを用いる手段です。
データクラスオブジェクト自身は、オブジェクトとしてコピーすることはできません:
$mydataclass:=OB Copy(ds.Employee) // null を返します
しかしながらデータクラスプロパティは取得可能です:
ARRAY TEXT($prop;0)
OB GET PROPERTY NAMES(ds.Employee;$prop)
// $prop にはすべてのデータクラス属性の名前が格納されます
属性
データクラスプロパティは、下地にあるフィールドやリレーションを説明する属性オブジェクトです。 例:
$nameAttribute:=ds.Company.name // クラス属性への参照
$revenuesAttribute:=ds.Company["revenues"] // 別の書き方
このコードは、$nameAttribute
および $revenuesAttribute
に、Company
クラスの name および revenues 属性の参照をそれぞれ代入します。 このシンタックスは属性内に保管されている値を返すのではありません。その代わりに、属性自身への参照を返します。 値を管理するためには、エンティティ を使用する必要があります。
テーブル内の適格なフィールドはすべて、親 データクラス の属性として利用可能です。 Open datastore
コマンドまたは REST リクエスト によってアクセスするリモートデータストアの場合、データクラスの属性として公開したい各フィールドについて 4D ストラクチャーのレベルで RESTリソースとして公開 プロパティを設定する必要があります。
ストレージ属性とリレーション属性
データクラス属性にはいくつかの種類があります。ストレージ、リレートエンティティ、リレートエンティティズです。 スカラーである属性 (単一の値のみを提供するもの) は標準の 4D データ型 (整数、テキスト、オブジェクトなど) をサポートします。
- ストレージ属性 は4D データベース内のフィールドに相当するもので、インデックスをつけることができます。 ストレージ属性に割り当てられた値は、保存時にエンティティの一部として保存されます。 ストレージ属性にアクセスしたとき、その値はデータストアから直接取り出されます。 ストレージ属性はエンティティを構成するもっとも基礎的な要素であり、名前とデータ型により定義されます。
- リレーション属性 は他のエンティティへのアクセスを提供します。 リレーション属性は単一のエンティティ (あるいはエンティティなし) あるいはエンティティセレクション (0からNまでのエンティティ) のどちらかになります。 リレーション属性はリレーショナルストラクチャーの "クラシックな" リレーションに基づいており、リレートエンティティあるいはリレートエンティティズへの直接的なアクセスを提供します。 リレーション属性は、ORDA においては名前を使用することで直接的に利用可能です。
たとえば、以下の部分的なデータベースストラクチャーと、そのリレーションプロパティについて考えます:
すべてのストレージ属性は自動的に利用可能です:
- Project データクラス内: "ID", "name", および "companyID"
- Company データクラス内: "ID", "name", および "discount"
これに加えて、以下のリレーション属性もまた自動的に利用可能になります:
- Project データクラス内: "リレートエンティティ" 型の theClient 属性。各 Project (クライアント) に対して最大 1つの Companyが あります。
- Company データクラス内: "リレートエンティティズ" 型のcompanyProjects 属性。各 Company に対して不定数の Project があります。
データベースリレーションの手動あるいは自動プロパティは、ORDA においては何の効力も持ちません。
すべてのデータクラス属性はデータクラスのプロパティとして公開されています:
これらのオブジェクトは属性を表しますが、データへのアクセスは与えないという点に注意してください。 データの読み書きは エンティティオブジェクト を通しておこなわれます。
計算属性とエイリアス属性
計算属性 と エイリアス属性 は "仮想" 属性です。 この属性値はアクセスされるたびに評価され、保存されません。 計算属性は、基礎となるデータベースストラクチャーには属しませんが、その上に構築され、データモデルの属性と同様に使用することができます。
エンティティ
エンティティとは、レコードに相当するものです。 実際にはデータベース内のレコードを参照するオブジェクトです。 エンティティは、データクラス のインスタンスとも解釈可能なオブジェクトです。 同時にエンティティは、データストアがもとにしているデータベースに相関するデータも格納しています。
エンティティの目的はデータの管理 (作成、更新、削除) です。 エンティティセレクションを用いてエンティティ参照を取得した場合、その参照にはエンティティセレクションについての情報も保持されるため、セレクションを走査することが可能です。
エンティティオブジェクト自身は、オブジェクトとしてコピーすることはできません:
$myentity:=OB Copy(ds.Employee.get(1)) // null を返します
しかしながらエンティティプロパティは取得可能です:
ARRAY TEXT($prop;0)
OB GET PROPERTY NAMES(ds.Employee.get(1);$prop)
// $prop にはすべてのエンティティ属性の名前が格納されます
エンティティセレクション
エンティティセレクションとは、同じデータクラスに所属する一つ以上のエンティティへの参照を格納しているオブジェクトのことです。 通常、クエリの結果として、あるいはリレーション属性の戻り値として作成されます。 エンティティセレクションは、データクラスから 0個、1個、あるいは X個のエンティティを格納することができます (X はデータクラスに格納されているエンティティの総数です)。
例:
var $e : cs.EmployeeSelection // EmployeeSelection クラスのオブジェクト変数として $e を宣言します
$e:=ds.Employee.all() // 結果のエンティティセレクションへの参照を $e に代入します
エンティティセレクションは "順列あり" あるいは "順列なし" 状態のどちらかです (後述参照)。
また、どのように作成されたか に応じて、エンティティセレクションは "共有可能" あるいは "追加可能" 状態のどちらかです。
エンティティセレクションオブジェクト自身は、オブジェクトとしてコピーすることはできません:
$myentitysel:=OB Copy(ds.Employee.all()) // null を返します
しかしながらエンティティセレクションプロパティは取得可能です:
ARRAY TEXT($prop;0)
OB GET PROPERTY NAMES(ds.Employee.all();$prop)
// $prop にはエンティティセレクションのプロパティ名が格納されます
// ("length", "00", "01"...)
エンティティセレクションの順列あり/順列なし
orderBy( )
メソッドを使用した場合、あるいは特定のオプションを使用した場合は除き、4D ORDA は最適化の観点からデフォルトで順列なしのエンティティセレクションを作成します。 このドキュメントでは、指定されている場合を除き、"エンティティセレクション" は "順列なしのエンティティセレクション" を指すこととします。
順列ありのエンティティセレクションは、必要な場合において、あるいはオプションを使用して特別に要求した場合に限り作成されます。たとえば、以下のような場合です:
- セレクション (タイプを問わず) に対して、あるいはデータクラスに対して
orderBy( )
を使った場合の戻り値 newSelection( )
メソッドにdk keep ordered
オプションを渡した場合の戻り値
順列なしのエンティティセレクションは以下のような場合に作成されます:
- セレクション (タイプを問わず) に対して、あるいはデータクラスに対して標準の
query( )
を使った場合の戻り値 - オプションなしで
newSelection( )
メソッドを使用した場合の戻り値 - 任意の演算メソッド (or( ), and( ), minus( ) ) を使った場合の戻り値 (入力セレクションタイプは問いません)。
次のエンティティセレクションは常に 順列あり となります:
- 4D Server からリモートクライアントに返されるエンティティセレクション
- リモートデータストアにおいて作成されるエンティティセレクション
順列ありのエンティティセレクションが順列なしのエンティティセレクションになった場合、重複したエンティティ参照はすべて削除されます。