Database Edition の機能の拡張

機能拡張を作成することにより、Visual Studio Team System Database Edition を拡張できます。 機能拡張により、リファクタリング、データ生成、単体テスト、データベース コード分析などの Database Edition の機能を拡張できます。 機能拡張を作成するときは基本機能の既存のフレームワークを使用するため、記述する必要のあるコードの量が大幅に削減されます。

機能拡張には、正しく定義された機能拡張ポイントがあります。 Database Edition の機能拡張を作成するために、Visual Studio SDK を用意する必要はありません。

一般的な高度なタスク

高度なタスク

関連する参照先

Database Edition の機能拡張の概念を理解する : 機能を拡張する前に、Database Edition における機能拡張のしくみを理解しておく必要があります。 このリリースでは、新しい機能を作成することも、独自のデータベース スキーマ プロバイダ (DSP: Database Schema Provider) を作成することもできません。 データベース スキーマ プロバイダは、特定のブランドの特定のバージョンのデータベース (SQL Server 2008 など) に固有のすべてのサービスを実装しています。 たとえば、対象のデータベースのスクリプトを読み書きするパーサー、スクリプトを表すスクリプト ドメイン オブジェクト モデル (スクリプト DOM)、データベース オブジェクトのオブジェクト、リレーションシップ、およびプロパティをモデル化するスキーマ モデルなどのサービスがあります。 Database Edition では、ユーザーが機能または機能拡張と対話するときに、それらの機能や機能拡張は、DSP サービス、スクリプト DOM、およびスキーマ モデルの組み合わせで動作します。

データベースのモデル化

Database Edition の機能拡張コンポーネント

機能拡張の種類

データベース スキーマ プロバイダのコア コンポーネント

新しい種類のデータベース リファクタリングのサポートを追加する : データベース リファクタリングの機能拡張を作成すると、新しい種類のデータベース リファクタリングを使用できるようになります。 新しいリファクタリングの種類ごとに、1 つ以上の新しいリファクタリング コントリビュータも必要となります。

データベース リファクタリングの機能拡張の概要

カスタムのデータベース リファクタリングの種類またはターゲットの作成

データベース リファクタリングの新しいターゲットのサポートを追加する : 既存の種類のデータベース リファクタリングを使用して、新しい種類の成果物 (テキスト ファイルなど) を更新したり、データベース情報を格納するサード パーティ アプリケーションから出力したりできるようになります。 新しいリファクタリングの種類を作成した場合は、データベース プロジェクトに含まれている成果物に対してその種類が機能するように、1 つ以上のリファクタリング コントリビュータを実装する必要があります。

データベース リファクタリングの機能拡張の概要

シナリオ : データベース リファクタリングの新しいターゲットのサポート

新しいデータベース コード分析規則を定義する : Database Edition に組み込まれている規則では検出されない問題を検出する、新しいデータベース コード分析規則を定義できます。

データベース コード分析用の追加規則の作成と登録

カスタム データ ジェネレータを作成する : カスタム データ ジェネレータを使用すると、機密情報は公開せずに現実的なテスト データを生成できます。 カスタム データ ジェネレータを作成することにより、Database Edition 2008 に用意されたデータ ジェネレータを補うことができます。

カスタム データ ジェネレータで独自のテスト データを生成する

データベース単体テストのカスタム条件を追加する : カスタム テスト条件を定義することにより、組み込みの単体テスト条件がサポートしていない方法で、データベース オブジェクトの動作を確認できます。

データベース単体テストのカスタム条件の定義

データベースのモデル化

Database Edition では、データベースをモデル化するために、データベースのデータ定義言語 (DDL: Data Definition Language) を作成するスクリプトと、それらのスクリプトを実行した場合に生成されるデータベースの両方をモデル化しています。 DDL スクリプトのモデルは、スクリプト DOM によって提供されます。 生成されるデータベースのモデルは、スキーマ モデルによって提供されます。 Database Edition からどちらかのモデルを削除すると、豊富な機能を提供したり、それらの機能を一貫して拡張したりすることが困難になります。

機能拡張コンポーネント間のデータ フロー

次の図は、各コンポーネントをデータが流れるしくみを示しています。

機能拡張コンポーネント間のデータ フロー
機能拡張コンポーネント間のデータ フロー

データベース オブジェクトは、DDL スクリプトの形でデータベース プロジェクトに保持されます。 データベース プロジェクトを開くと、これらのスクリプトが読み込まれ、スクリプト DOM モデルとスキーマ モデルの 2 つのモデルが設定されます。 Database Edition の各機能は、この両方のモデルとやり取りします。データベース オブジェクトへの変更を保存すると、変更内容が DDL スクリプトに戻されて保持されます。

Database Edition の機能拡張コンポーネント

次の図は、Database Edition の機能を拡張できるようにするためにやり取りする各コンポーネントを示しています。

機能拡張コンポーネント間の通信
Database Edition の機能拡張コンポーネント

データベース プロジェクトを開いたり作成したりすると、機能拡張マネージャ コンポーネントが登録済みのデータベース スキーマ プロバイダを読み込みます。 データベース スキーマ プロバイダ (DSP) の特定の機能を使用する場合、機能拡張マネージャ コンポーネントは、それらの機能とその DSP をサポートする拡張機能を読み込みます。 たとえば、名前の変更リファクタリング機能を使用して SQL Server 2008 データベースのオブジェクトの名前を変更する場合、SQL Server 2008 用のリファクタリングの種類およびコントリビュータと共にリファクタリング機能が読み込まれます。

機能拡張マネージャ

Database Edition を実行すると、すべてのデータベース プロジェクト、スキーマ プロバイダ、機能、および機能拡張が単一の ExtensionManager とやり取りします。 機能拡張マネージャは、各データベース プロジェクトの DatabaseSchemaProvider から派生した単一のインスタンスを読み込みます。 たとえば、Database Edition で Microsoft SQL Server 2005 プロジェクトを開くと、機能拡張マネージャが (DatabaseSchemaProvider から派生した) Sql90DatabaseSchemaProvider のインスタンスを読み込みます。

機能拡張マネージャは、拡張機能で実装されているインターフェイスの型に基づいて拡張機能を読み込みます。 たとえば、データベース単体テスト機能を使用する場合、機能拡張マネージャは TestCondition 基本クラスを継承する登録済みの拡張機能のリストを返します。これらの拡張機能は、データベース プロジェクトのデータベース スキーマ プロバイダと互換性があります。

機能拡張の互換性

リファクタリングやスタティック コード分析などの機能は、DSP に固有のコンポーネントと、すべての DSP をサポートするコンポーネント (DSP に柔軟なコンポーネント) で構成されます。 機能拡張を定義するときは、特定の DSP または基本 DSP とその拡張機能の互換性を宣言し、拡張機能が適切なプロジェクトの種類に対してのみ読み込まれるようにします。 たとえば、拡張機能が Sql90DatabaseSchemaProvider (SQL Server 2005 プロジェクトに制限) または SqlDatabaseSchemaProvider (SQL Server 2000、SQL Server 2005、および SQL Server 2008 の各 DSP の基本クラス) と互換性があることを宣言できます。 また、拡張機能が複数の特定の DSP と互換性があることを宣言することもできます。 この方法は、今後のリリースで機能が中止されるかどうか不明である場合に使用します。 機能がすべての DSP と互換性があることを宣言するには、DatabaseSchemaProvider 基本クラスと互換性があるものとして機能を宣言します。

1 つの DSP と互換性のある拡張機能を定義します。

// SqlSchemaObjectDesigners is defined as compatible with all Sql 
// database services providers.  
[DatabaseServicesProviderCompatibility(typeof(SqlDatabaseServicesProvider))]
internal class SqlSchemaObjectDesigners : ISchemaObjectDesigners
{
}

複数の DSP と互換性のある拡張機能を定義します。

// Extension InconclusiveCondition is defined as compatible with all 
// SQL Server database services providers and Oracle database 
// services providers.
[DatabaseServicesProviderCompatibility(typeof(SqlDatabaseServicesProvider))]
[DatabaseServicesProviderCompatibility(typeof(OracleDatabaseServicesProvider))]
public sealed class InconclusiveCondition : TestCondition
{
}

すべての DSP と互換性のある拡張機能を定義します。

// Extension ReportingService is defined as compatible with all
// database services providers.
[DatabaseServicesProviderCompatibility(typeof(DatabaseServicesProvider))]
internal class ReportingService : IReportingService
{
}

どの DSP とも互換性のない拡張機能を定義します。

// Extension ExecutionTimeCondition is defined as compatible with no
// database services providers.  That means if a feature
// has an ExtensionManager constructed with null, it will load
// those extensions defined as binding to 
// DspCompatibilityCategory.None
[DatabaseServicesProviderCompatibility(DspCompatibilityCategory.None)]
public sealed class ExecutionTimeCondition : TestCondition
{
}

機能拡張の種類

Database Edition の一部の機能を強化する機能拡張を作成できます。 作成できる拡張機能の種類を次の表に示します。

機能

拡張機能の種類

説明

データベース単体テスト

単体テスト条件

テストが正常に完了したかどうかを判断するためのカスタム アサーションを追加できます。 単体テスト API の多くはパブリックですが、機能拡張ポイントではありません。 これらの API は、Visual C# や Visual Basic などのマネージ コードで記述されたデータベース単体テストを作成するために使用されます。 詳細については、「データベース単体テストのカスタム条件の定義」を参照してください。

データ生成

データ ジェネレータ

Database Edition にデータ ジェネレータが用意されている場合は、機能拡張 API を使用してカスタム データ ジェネレータを作成できます。 詳細については、「カスタム データ ジェネレータで独自のテスト データを生成する」を参照してください。

データベース コード分析

コード分析規則

データベース コード内の特定の問題をチェックする独自のコード分析規則を定義できます。 詳細については、「データベース コード分析用の追加規則の作成と登録」を参照してください。

データベース リファクタリング

リファクタリングのターゲット

新しいターゲット (新しいファイルの種類など) で機能するように、既存のリファクタリングの種類を拡張できます。 詳細については、「チュートリアル : データベースの名前の変更リファクタリングを拡張し、テキスト ファイルで実行する」を参照してください。

データベース リファクタリング

ファクタリングの種類

入れ子になった条件記述をガード句で置き換えるなど、新しいリファクタリングの種類を作成できます。 詳細については、「カスタムのデータベース リファクタリングの種類またはターゲットの作成」を参照してください。

データベース スキーマ プロバイダのコア コンポーネント

データベース スキーマ プロバイダ (DSP) は、次の 3 つのコンポーネント グループで構成されます。

  • スクリプト DOM - DDL ステートメントと DML ステートメントの両方を含む任意の SQL スクリプトをモデル化するオブジェクト モデルとサポート サービス

  • スキーマ モデル - データベース インスタンス内のオブジェクト (テーブル、ビュー、ストアド プロシージャなど) をモデル化するオブジェクト モデルとサポート サービス

  • ユーザー インタラクション サービス – コア コンポーネントがユーザー インターフェイス リソース (オブジェクトの名前を表す文字列、オブジェクトの種類とカテゴリを表すアイコン、オブジェクトを表示する階層など) にアクセスできるようにするサービスの集まり

DSP の主要機能は、DDL スクリプトの処理をスクリプト DOM とスキーマ モデルの両方で表現できるようにすることと、この 2 つのモデル表現からスクリプトを再生成する逆方向の機能を実現することです。

スクリプト DOM

スクリプト DOM は、DDL スクリプトを解析して、そのスクリプトを表すオブジェクト モデルに変換する実装を提供します。 また、スクリプト DOM は、モデルから元のスクリプトを再生成する実装も提供します。

次の図は、スクリプト DOM をデータが流れるしくみを示しています。

スクリプト DOM のデータ フロー
スクリプト DOM のデータ フロー

スクリプト DOM パーサーは、非構造化テキスト ファイルに格納されたスクリプトを IScriptFragment インターフェイスを継承するオブジェクトに変換します。 スクリプト DOM のスクリプト ジェネレータは、IScriptFragment インターフェイスを継承するオブジェクトを取得し、元のスクリプトを生成します。 Database Edition に組み込まれている SQL Server 用のデータベース スキーマ プロバイダでは、IScriptFragment は抽象構文ツリー (AST: Abstract Syntax Tree) とトークン ストリームを抽出します。

トークンは、スクリプトの非構造化表現です。 コレクション内の各トークンには、次の情報が含まれます。

  • トークンの種類 (キーワードやリテラル文字列など)

  • トークン文字列

  • そのトークンが出現したソース ファイル

  • ソース ファイル内でのトークンの出現位置のオフセット

AST は、スクリプトの構造を表すものです。 AST の各ノードは、バッチ ステートメント、ステートメント、またはステートメントのコンポーネント (式など) を表します。 AST は、スクリプトの解析後、スクリプトを分析するために使用されます。 また、プログラムによってスクリプトをビルドするときにも AST が使用されます。

スキーマ モデル

スキーマ モデル表現は、ライブ データベース インスタンスをモデル化するインターフェイス ベースのオブジェクト モデルです。 各インターフェイスは、すべての DSP が共有する 1 つの抽象化レイヤと、モデルのより具体的な詳細情報を対象とする任意の数の抽象化レイヤが含まれた派生階層に配置されます。 たとえば、ISql90Table インターフェイスは ISqlTable を継承し、ISqlTable は ITable 抽象化レイヤ インターフェイスを継承します。

スキーマ モデルでは、IScriptFragment オブジェクトを取得し、スキーマ モデル要素に変換します (また、スキーマ モデル要素から IScriptFragment オブジェクトへの逆方向の変換も実行します)。 スキーマ モデルは、複数のモデル コンポーザ実装で構成されます。 各実装では、システム内の他のリソースからモデルを作成します。 たとえば、ScriptModelComposer は、データベース プロジェクトに保持されているスクリプト ファイルからモデルを構成します。

スキーマ モデル インフラストラクチャ (ModelStore とそのサポート クラス) は、モデル要素から直接統合された Script DOM 参照を実装しています。 そのため、任意のスクリプトを含むストアド プロシージャなどのオブジェクトをモデル化できます。

スキーマ モデルは、要素と注釈のコレクションで構成されます。 各要素は、モデル化される成果物 (テーブル、ビュー、ストアド プロシージャ、トリガ、列など) を示します。 注釈は、任意のデータをモデルに関連付けるために使用されます。 注釈は、データベース プロジェクトのコア コンポーネントによって使用されますが、プロジェクト機能や機能拡張で使用することもできます。 要素と注釈には名前を付けることも、匿名にすることもできます。

モデル要素

要素は、プロパティとリレーションシップから成ります。 プロパティは、整数、ブール値、文字列などの基本データを表し、モデルの詳細情報を取得するために使用されます。 リレーションシップは、要素間の型指定された名前付きの関係を表します。 たとえば、ITable 要素は、テーブルとその列を関連付ける "Columns" という名前の IColumn 型のリレーションシップを保持します。

リレーションシップには、次の 3 つの基本的な種類があります。

  • ピア – 任意の方法で 2 つの要素間の依存関係を表します。 SQL Server では、ビューとテーブル間のリレーションシップをピア リレーションシップとしてモデル化するのが最適です。

  • 構成 - 他の要素で構成される 1 つの要素を表します。 SQL Server では、テーブルとその列間のリレーションシップを構成リレーションシップとしてモデル化するのが最適です。 構成リレーションシップの基本原則の 1 つは、2 つの要素が 1 つのアクションとして同時に作成されることです。 作成または削除する場合に、要素に依存関係順序はありません。 ただし、結合性のある依存関係を実現するために、親から子という依存関係の方向はモデルで保持されます。 たとえば、列に特定の型への依存関係がある場合、親テーブルの列への依存関係は、親テーブルもその型に依存していることを意味します。

  • 階層 - 階層構造を表します。 階層リレーションシップでは、依存関係の方向が親から子ではなく、子から親であるため、構成リレーションシップとは異なります。 SQL Server での階層リレーションシップの例は、スキーマと所有されているオブジェクト (テーブルやビューなど) 間のリレーションシップです。 テーブルは、そのスキーマとの階層リレーションシップに含まれます。

次の図は、スキーマ モデルで表すことができる 3 種類のリレーションシップを示しています。

スキーマ モデルのオブジェクト リレーションシップ
スキーマ モデルのオブジェクト リレーションシップ

モデル内の各リレーションシップでは、多重リレーションシップと単一リレーションシップのどちらであるかを宣言します。 どの場合でも、要素は空のリレーションシップを保持できます。 モデルは、実際の成果物の不完全なモデルであってもかまいません。

ストア実装で次の機能をサポートするために、要素はインターフェイスに基づいています。

  • 要素の厳密な型指定 (ID)

  • 多重継承

    • システムの DSP に柔軟な部分と DSP 固有の部分の両方をサポートするため

    • これ以外の方法では関連のない要素の型全体で "品質" の共有をサポートするため

  • バージョンの柔軟性と拡張性

すべてのモデル要素クラスは、IModelElement パブリック インターフェイスを実装しています。 プロパティ、リレーションシップ、および注釈には、このクラスの ModelStore メタデータ API を使用してアクセスできます。 ITable などのインターフェイスを使用すると、より簡単で保守が容易な方法でプロパティとリレーションシップにアクセスできるようになります (コンパイル時にバインドされます)。

モデル注釈

要素と同様に、注釈は複数のプロパティから成ります。 要素とは異なり、注釈はリレーションシップに含まれません。 代わりに、注釈は要素またはモデル ストア自体にアタッチされます。 注釈は厳密に型指定されます。注釈の 1 つのインスタンスは、モデル ストアだけでなく複数の要素にアタッチできます。 モデルにアタッチされた注釈は、そのモデルに対して "グローバル" である注釈インスタンスを表します。

参照

概念

Database Edition の用語の概要