地元の物好きなSEの今日この頃(´ー`)です。
凄いというか突拍子もないような提案を某所でしてたのですが、もちろんある程度の目算があってのことですし、実際に動作しているので報告。
COBOLのOPEN,READ,START,CLOSE等のファイル操作をmydb_open, mydb_read, mydb_start, mydb_close等のperlで書いたsubを呼び出すようにして、OpenCOBOLからMySQLへの操作を実現しています。
329700* READ IN9-F NEXT
329800* AT END MOVE 0 TO W-DUMMY.
329900 CALL "cob_perl_call" USING "mydb_read"
330000 "IN9-F".
330100 CALL "cob_perl_results" USING
330200 COBPERL-STATUS LN010-FSTAT1 XIQR0030.
330300 IF COBPERL-STATUS NOT = ZERO
330400 MOVE 0 TO W-DUMMY
330500 END-IF.
330600 IF LN010-FSTAT1 = ZERO
330700 IF (W-OKEI = XQ030-SYOCD) AND
330800 (W-YY = XQ030-NENSU)
上記のような置き換えですね。329700、329800行のREAD文をCALL "cob_perl_call"と"cob_perl_results"およびIF文で置き換えています(329900~330500)。cob_perl_resultsでperlスクリプトからの戻り値を得ています。mydb_readですが:
306 sub mydb_read {
307 my $fh = shift;
308 if (!exists($COBPERL_DB::dbnames{$fh})) {
309 die "";
310 }
311 my $db = $COBPERL_DB::dbnames{$fh};
312 my $result = $db->Read;
313 ($db->{'fstatus'}, $db->{'status'}, $result);
314 }
こんな感じですね。リストで返した値がcob_perl_resultsで取れるようになっています。$db->{'status'}にはREADを実行した結果のファイル状態が入っているわけです。そのようにしてCOBOL側の動作をエミュレートしていった結果、ほとんどの部分についてスムーズに実装することが出来ました。速度的にもう少し欲しい部分もありますが、少なくともプロトタイピングが早期に出来たことはありがたかったです。
速度に関しては、OpenCOBOLのISAM形式(といってもvbISAMを使用していますが)を使用した場合に比べ未だ数倍ほど遅いのですが定型的な部分やコアな処理部分のアルゴリズムの設計がかたまったら改めてC言語での実装も可能と思います。DBI部分だけの速度ならISAM形式の1.2倍くらいでした。この作業の中でperl script の高速化について色々なノウハウが溜まったのですが、これはまた別の機会にでも(ifより三項演算子が圧倒的に速い等)
移植にかかる工数ですが、実際もの凄く削減できています(ちょっと口では言えないし書けないくらい)。次はこれとphp_opencobol.soを連携させてPHPからOpenCOBOLのバイナリへ変数を渡す/値を取り出してサクサクとWebアプリケーション化を行っていきます。
Posted by minemaz at 2008年12月13日 15:58