Symfoware Server アプリケーション開発ガイド(埋込みSQL編) - FUJITSU - |
目次 索引 |
第4章 ルーチンを利用するアプリケーションの作成 | > 4.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) リンクするライブラリの再設定
ファンクションルーチンのライブラリを作成します。
ライブラリ作成についての詳細は“ライブラリの作成”を参照してください。
ファンクションルーチンをテストするためのテストドライバの実行形式を作成します。
テストドライバのプログラム例についてはUNIX系の場合を参照してください。
以下にテストドライバ実行形式の作成例を示します。
例
テストドライバ実行形式(ftestdrv001)の作成例
cl ftestdrv001.c /Feftestdrv001 -DNT
ファンクションルーチンから異常通知する場合のテストで使用するダミーSQLSignalMSG関数のライブラリを作成します。
ダミーSQLSignalMSG関数のプログラム例についてはUNIX系の場合を参照してください。
以下にダミーSQLSignalMSG関数のライブラリ作成例を示します。
例
ダミーSQLSignalMSG関数のライブラリ作成例
Static Libraryを作成します。
Microsoft(R) Visual Studioでの作成手順の例を以下に示します。
[ファイル(F)]メニューから、[新規作成(N)]で[プロジェクト(P)]を選択します。
[新しいプロジェクト]ウインドウにて、[プロジェクトの種類(P)]で[Visual C++]の[Win32]を選択し、[テンプレート(T)]で[Win32 プロジェクト]を選択します。
[新しいプロジェクト]ウインドウにて、[プロジェクト名(N)]を指定し、[場所(L)]にライブラリ作成場所を指定します。[ソリューションのディレクトリを作成(D)]のチェックボックスのチェックを外します。[OK]を選択します。
例
プロジェクト名 = F3CWSQLSIGM 位置 = D:\FORSYMFO\FUNCMAKE\F3CWSQLSIGM指定した位置に、作成したCプログラムファイルを格納しておきます。
[Win32 アプリケーション ウィザード]ウインドウの[Win32 アプリケーション ウィザードへようこそ]の画面にて[次へ>]を選択します。
[Win32 アプリケーション ウィザード]ウインドウの[アプリケーションの設定]の画面にて[アプリケーションの種類]で[スタティック ライブラリ(S)]を選択します。[追加オプション]で[プリコンパイル済みヘッダー(P)]のチェックボックスのチェックを外します。[完了]を選択します。
[プロジェクト(P)]の、[既存項目の追加(G)]から、作成したCプログラムファイルをプロジェクトに追加します。
例
D:\FORSYMFO\FUNCMAKE\F3CWSQLSIGM\FDUMMYMSG.C
[ビルド(B)]から[ソリューションのビルド(B)]を選択して、ライブラリを作成します。
単体テストの終了後は、ダミーSQLSignalMSG関数のライブラリの設定を外し、Symfoware/RDBのSQLSignalMSG関数のライブラリを設定する必要があります。
以下に、ライブラリの再設定例を示します。
例
ライブラリの再設定例
Microsoft(R) Visual Studioでの作成手順の例を以下に示します。
[ファイル(F)]メニューから、[開く(O)]で[プロジェクト/ソリューション(P)]を選択しファンクションルーチンのライブラリを指定します。
例
ファイル場所 = D:\FORSYMFO\FUNCMAKE\USERFUNC001ファイル名 = USERFUNC001.sln
ファンクションルーチンのライブラリ内で使用したダミーSQLSignalMSG関数の設定を外しSymfoware/RDBのSQLSignalMSG関数のライブラリを設定します。
[ツール(T)]から[オプション(O)]を選択し、[プロジェクトおよびソリューション]の[VC++ ディレクトリ]を開きます。
[ディレクトリを表示するプロジェクト(S)]に“ライブラリファイル”を選択して、[ディレクトリ]にダミーSQLSignalMSG関数のライブラリが存在する場合は指定を外し、<サーバ機能のインストール先>\ESQL\LIBまたは<クライアント機能のインストール先>\ESQL\LIBの指定を追加します。
なお、ライブラリの対象プラットフォームは、サーバが動作するプラットフォームと同じにします。
[ビルド(B)]から[ソリューションのリビルド(R)]を選択して、ライブラリを再作成します。
作成したライブラリを、ファンクションルーチン定義文のLIBRARY句で指定するディレクトリに格納します。
例
D:\FORSYMFO\FUNCMAKE\USERFUNC001\RELEASE\USERFUNC001.DLL ↓ 複写 D:\FORSYMFO\FUNCLIB\USERFUNC001.DLL
テストドライバの実行例
drv002: LoadLibrary start drv002: GetProcAddress 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
目次 索引 |