| Symfoware(R) Server RDBユーザーズガイド 応用プログラム開発編 - FUJITSU - | 
| 目次
			索引    | 
 第3章 ルーチンを利用する応用プログラムの作成方法
第3章 ルーチンを利用する応用プログラムの作成方法
	 3.2 ファンクションルーチンを利用する場合
3.2 ファンクションルーチンを利用する場合
作成したファンクションルーチンは、Symfoware/RDBを介して実行する前に、テストドライバを利用して単体テストを行い、十分な品質を確保しておく必要があります。
テストドライバが直接ファンクションルーチンのライブラリを呼び出すことで、Symfoware/RDBを介さずに単体テストを行うことができます。
また、SQLSignalMSG関数を使用してファンクションルーチンから異常通知するプログラムを作成した場合の単体テストは、ダミーのSQLSignalMSG関数を用意し、Symfoware/RDBを介さずにテストを行う必要があります。

(1) ファンクションルーチンのライブラリ作成
(2) テストドライバの実行形式作成
(3) ダミーSQLSignalMSG関数のライブラリ作成
(4) リンクするライブラリの設定
(5) リンクするライブラリの再設定
ファンクションルーチンのライブラリを作成します。
ライブラリ作成についての詳細は“ライブラリの作成”を参照してください。
以下にファンクションルーチンのライブラリ作成例を示します。
例
ファンクションルーチンのライブラリ作成例
| cc -G -o /usr/local/lib/libuserfunc001.so userfunc001.c -mt | 
例
ファンクションルーチンのライブラリ作成例
| gcc -shared -o /usr/local/lib/libuserfunc001.so userfunc001.c -D_REENTRANT | 
ファンクションルーチンをテストするためのテストドライバの実行形式を作成します。
テストドライバのプログラム例およびテストドライバ実行形式の作成例を以下に示します。
例
ファンクションルーチン“USERFUNC002”用テストドライバ(ftestdrv001.c)のプログラム例
| /*-------------------------------------------------------------*/
/* ファンクションルーチン"USERFUNC002"用テストドライバ         */
/*-------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#ifdef NT
#include <windows.h>
#else
#include <dlfcn.h>
#endif
/* 引数データのポインタリスト */
typedef struct in_ptr_list_tag {
    void  *ptr[2];    /* ファンクションのパラメタの個数×2 */
} in_ptr_list_t;
/* 結果データのポインタリスト */
typedef struct out_ptr_list_tag {
    void  *ptr[2];    /* 返却データと標識データの格納先 */
} out_ptr_list_t;
/* 呼び出し関数名 */
#define FUNC_NAME  "UserFunc002"
/* ライブラリのパス */
#ifdef NT
#define FUNC_PATH  "D:\\FORSYMFO\\FUNCLIB\\USERFUNC002.DLL"
#else
#define FUNC_PATH  "/export/home/kanda/Function/libuserfunc002.so"
#endif
int main()
{
    void        *handle_p;       /* dlopenのハンドラ       */
    void        (*sym_p)();      /* アドレスベクタ         */
    int         data1;           /* 引数1データ格納用     */
    short       ind1;            /* 引数1標識データ格納   */
    char        ret[43];         /* 結果データ格納用       */
    short       r_ind;           /* 結果の標識データ格納用 */
    short       ret_size;        /* 結果データの実データ長 */
    char        buf[41];         /* 結果データ表示用       */
    /* 入出力のポインタリスト */
    in_ptr_list_t   in_ptr_list;
    out_ptr_list_t  out_ptr_list;
#ifdef NT
    printf("drv002:LoadLibrary start\n");
    /* ファンクションルーチンのライブラリをオープン */
    handle_p = LoadLibrary(FUNC_PATH);
#else
    printf("drv002:dlopen start\n");
    /* ファンクションルーチンのライブラリをオープン */
    handle_p = dlopen(FUNC_PATH, RTLD_NOW);
#endif
    if (handle_p == NULL) {
        return(1);
    }
#ifdef NT
    printf("drv002:GetProcAddress start\n");
    /* ライブラリの入口アドレスの取得 */
    sym_p = (void (*)())GetProcAddress(handle_p, FUNC_NAME);
    if (sym_p == NULL) {
        FreeLibrary(handle_p);
        return(2);
    }
#else
    printf("drv002:dlsym start\n");
    /* ライブラリの入口アドレスの取得 */
    sym_p = (void (*)())dlsym(handle_p, FUNC_NAME);
    /* ライブラリの入口アドレスの取得 */
    sym_p = (void (*)())dlsym(handle_p, FUNC_NAME);
    if (sym_p == NULL) {
        dlclose(handle_p);
        return(2);
    }
#endif
    printf("drv002:make indata\n");
    /* 入力データの作成 */
    data1 = -100;                   /* 負の値 */
    ind1  = 0;
    in_ptr_list.ptr[0] = &data1;    /* 引数1のデータ     */
    in_ptr_list.ptr[1] = &ind1;     /* 引数1の標識データ */
    printf("drv002:make outdata area\n");
    /* 結果データ格納先の準備 */
    memset(ret, 0x00, sizeof(ret));
    r_ind = -1;
    out_ptr_list.ptr[0] = ret;      /* 結果データ格納先     */
    out_ptr_list.ptr[1] = &r_ind;   /* 結果標識データ格納先 */
    /* ファンクションルーチンの呼び出し */
    printf("drv002:call func\n");
    (*sym_p)(&in_ptr_list, &out_ptr_list);
    printf("drv002:call func end\n");
    if (r_ind < 0) {
        /* NULL値 */
        printf("drv002:ret = NULL\n");
    }
    else {
        /* VARCHARデータ長の取り出し */
        memcpy(&ret_size, ret, sizeof(short));
        printf("drv002:ret_size=%d\n", ret_size);
        /* VARCHARデータの取り出し */
        memset(buf, 0x00, sizeof(buf));
        memcpy(buf, ret + sizeof(short), ret_size);
        printf("drv002:return value = %s\n", buf);
    }
    /* ライブラリのクローズ */
#ifdef NT
    FreeLibrary(handle_p);
#else
    dlclose(handle_p);#endif
    printf("drv002:end\n");return(0); } | 
例
テストドライバ実行形式(ftestdrv001)の作成例
| cc -o ftestdrv001 ftestdrv001.c -ldl | 
例
テストドライバ実行形式(ftestdrv001)の作成例
| gcc -o ftestdrv001 ftestdrv001.c -ldl | 
ファンクションルーチンから異常通知する場合のテストで使用するダミーSQLSignalMSG関数のライブラリを作成します。
ダミーSQLSignalMSG関数のプログラム例およびダミーSQLSignalMSG関数のライブラリ作成例を以下に示します。
例
ダミーSQLSignalMSG関数“SQLSignalMSG”(fdummymsg.c)のプログラム例
| /*-----------------------------------------------------------*/
/* SQLSignalMSG関数のダミープログラム                        */
/*-----------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#define MSG1 "JYP4557E ファンクションルーチン“%s”から例外が送信されました.例外メッセージ=“%s”"
void  SQLSignalMSG(char *msg_p)
{
    char    msg_data[1024];
    memset(msg_data,0x00,sizeof(msg_data));
    sprintf(msg_data,MSG1,"TestFunction",msg_p);
    /* SQLSTATE 出力  */
    printf("SQLSTATE = 60000\n");
    /* SQLMSG 出力 */
    printf("SQLMSG   = %s\n",msg_data);
    return;
} | 
例
ダミーSQLSignalMSG関数のライブラリ作成例
| cc -G -o /usr/local2/lib/libsqlsigm.so fdummymsg.c | 
例
ダミーSQLSignalMSG関数のライブラリ作成例
| gcc -shared -o /usr/local/lib/libsqlsigm.so fdummymsg.c | 
単体テストを実行するために、ダミーSQLSignalMSG関数のライブラリおよびファンクションルーチンのライブラリをLD_LIBRARY_PATHに設定します。
以下に、2つのライブラリの設定例を示します。
例
ダミーSQLSignalMSG関数のライブラリおよびファンクションルーチンのライブラリの設定例
| setenv LD_LIBRARY_PATH /usr/local2/lib:/usr/local/lib
                            (1)              (2) | 
(1) ダミーSQLSignalMSG関数のライブラリ
(2) ファンクションルーチンのライブラリ
単体テストの終了後は、ダミーSQLSignalMSG関数のライブラリをLD_LIBRARY_PATHから外し、Symfoware/RDBのSQLSignalMSG関数のライブラリをLD_LIBRARY_PATHに設定する必要があります。
以下に、ライブラリの再設定例を示します。
例
ライブラリの再設定例
| setenv LD_LIBRARY_PATH /usr/local/lib:/opt/FSUNrdb2b/lib: …
                            (1)              (2) | 
(1) ファンクションルーチンのライブラリ
(2) Symfoware/RDB のSQLSignalMSG関数ライブラリ

テストドライバの実行例
| drv002:dlopen start drv002:dlsym start drv002:make indata drv002:make outdata area drv002:call func SQLSTATE = 60000 SQLMSG = JYP4557E ファンクションルーチン“TestFunction”から例外 が送信されました.例外メッセージ=“引数1が負の値です” drv002:call func end drv002:ret = NULL drv002:end | 

(1) ファンクションルーチンのライブラリ作成
(2) テストドライバの実行形式作成
(3) ダミーSQLSignalMSG関数のライブラリ作成
(4) リンクするライブラリの再設定
ファンクションルーチンのライブラリを作成します。
ライブラリ作成についての詳細は“ライブラリの作成”を参照してください。
以下にファンクションルーチンのライブラリ作成例を示します。
例
ファンクションルーチンのライブラリ作成例
Dynamic-Link Libraryを作成します。Microsoft(R) Visual Studioでの作成手順の例を以下に示します。
[ファイル(F)]メニューから、[新規作成(N)]を選択します。
[プロジェクト]タグを開き、[Win32 Dynamic-Link Library]を選択します。
[プロジェクト名]を指定し、[位置]にライブラリ作成場所を指定します。
例
指定した位置に、作成したCプログラムファイルを格納しておきます。
[プロジェクト(P)]の、[プロジェクトへ追加(A)]から、[ファイル]を選択し、作成したCプログラムファイルをプロジェクトに追加します。
例
ファンクションルーチンのライブラリ内でダミーSQLSignalMSG関数を使用する場合は、ライブラリF3CWSQLSIGM.LIBを結合する必要があります。さらに、インクルードファイルSQLSIGM.Hをインクルードする必要があります。
[プロジェクト(P)]から[設定(S)]を選択し、[リンク]タグを開いて、[オブジェクト/ライブラリモジュール]の指定にライブラリ名F3CWSQLSIGM.LIBを追加します。
[ツール(T)]から[オプション(O)]を選択し、[ディレクトリ]タグを開きます。
[表示するディレクトリ]に“インクルードファイル”を選択して、[ディレクトリ]にx:\SFWSV\ESQL\INCLUDEが指定されていることを確認します。指定されていなければ、指定を追加します。
[表示するディレクトリ]に“ライブラリファイル”を選択して、[ディレクトリ]にダミーSQLSignalMSG関数のライブラリが存在するディレクトリが指定されていることを確認します。指定されていなければ、指定を追加します。追加する場合は、x:\SFWSV\ESQL\LIBの前に指定してください。
3)および4)における“x”には、Symfoware/RDBをインストールしたドライブ名を指定します。
[ビルド(B)]から[ビルド(B)]を選択して、ライブラリを作成します。
作成したライブラリを、ファンクションルーチン定義文のLIBRARY句で指定するディレクトリに格納します。
例
D:\FORSYMFO\FUNCMAKE\USERFUNC001\RELEASE\USERFUNC001.DLL ↓ 複写 D:\FORSYMFO\FUNCLIB\USERFUNC001.DLL
ファンクションルーチンをテストするためのテストドライバの実行形式を作成します。
テストドライバのプログラム例についてはUNIX系の場合を参照してください。
以下にテストドライバ実行形式の作成例を示します。
例
テストドライバ実行形式(ftestdrv001)の作成例
| cl ftestdrv001.c -o ftestdrv001 -DNT | 
ファンクションルーチンから異常通知する場合のテストで使用するダミーSQLSignalMSG関数のライブラリを作成します。
ダミーSQLSignalMSG関数のプログラム例についてはUNIX系の場合を参照してください。
以下にダミーSQLSignalMSG関数のライブラリ作成例を示します。
例
ダミーSQLSignalMSG関数のライブラリ作成例
Static Libraryを作成します。Microsoft(R) Visual Studioでの作成手順の例を以下に示します。
[ファイル(F)]メニューから、[新規作成(N)]を選択します。
[プロジェクト]タグを開き、[Win32 Static Library]を選択します。
[プロジェクト名]を指定し、[位置]にライブラリ作成場所を指定します。
例
指定した位置に、作成したCプログラムファイルを格納しておきます。
[プロジェクト(P)]の、[プロジェクトへ追加(A)]から、[ファイル]を選択し、作成したCプログラムファイルをプロジェクトに追加します。
例
[ビルド(B)]から[ビルド(B)]を選択して、ライブラリを作成します。
単体テストの終了後は、ダミーSQLSignalMSG関数のライブラリの設定を外し、Symfoware/RDBのSQLSignalMSG関数のライブラリを設定する必要があります。
以下に、ライブラリの再設定例を示します。
例
ライブラリの再設定例
Microsoft(R) Visual Studioでの作成手順の例を以下に示します。
[ファイル(F)]メニューから、[ワークスペースを開く(W)]を選択しファンクションルーチンのライブラリを指定します。
例
ファンクションルーチンのライブラリ内で使用したダミーSQLSignalMSG関数の設定を外しSymfoware/RDBのSQLSignalMSG関数のライブラリを設定します。
[ツール(T)]から[オプション(O)]を選択し、[ディレクトリ]タグを開きます。
[表示するディレクトリ]に“ライブラリファイル”を選択して、[ディレクトリ]にダミーSQLSignalMSG関数のライブラリが存在する場合は指定を外し、x:\SFWSV\ESQL\LIBの指定を追加します。
2)における“x”には、Symfoware/RDBをインストールしたドライブ名を指定します。
[ビルド(B)]から[リビルド(R)]を選択して、ライブラリを再作成します。
作成したライブラリを、ファンクションルーチン定義文のLIBRARY句で指定するディレクトリに格納します。
例
D:\FORSYMFO\FUNCMAKE\USERFUNC001\RELEASE\USERFUNC001.DLL ↓ 複写 D:\FORSYMFO\FUNCLIB\USERFUNC001.DLL

テストドライバの実行例
| drv002:dlopen start drv002:dlsym start drv002:make indata drv002:make outdata area drv002:call func SQLSTATE = 60000 SQLMSG = JYP4557E ファンクションルーチン"TestFunction"から例外が送信されました.例外メッセージ="引数1が負の値です" drv002:call func end drv002:ret = NULL drv002:end | 
| 目次
			索引    |