カテゴリー別アーカイブ: Visual Basic

oo4oを倒した話 by @masaru_b_cl #vbadvent2015

この記事はVisual Basic Advent Calendar 2015の22日分です。昨日は@hilaponさんの「Visual Basic 2015 の新機能(その3) – (憂国のプログラマ Hatena版 改め) 周回遅れのブルース」でした。

問題

未だにまれによくあるVB6→VB(.NET)への移行の際、問題となるのがサードパーティ製品の扱いです。その中でもRDBMSへのアクセスを行うプロバイダーの変更は特に厄介です。

もちろん、データアクセス処理を適度に抽象化して、一箇所にまとめているようであれば、影響は小規模で済むのですが、VB6といえば良くも悪くも「誰でも」システムが作れたので、まぁお察しということで。

そんな状況の中、Oracle Database 11gまでサポートしていたoo4o(Oracle Objects for OLE)が、Oracle Database 12cではとうとうサポートが打ち切られてしまい、ODP.NETへの乗り換えを余儀なくされてしまいました。とはいえ、システム内のあちこちにoo4oを直に叩くコードが散乱していて、すべて書き換えるのは無理があります。

解決法

というわけでこんな感じのものを作って、oo4oを倒すことに成功しました。

https://github.com/masaru-b-cl/Oo4oBuster

oo4o Buster

oo4oを操作するコードをなるべく変更せずに、ODP.NETへ置き換えるためのサポートを行います。

必須要件

  • ODP.NET 11g or higher

使い方

Using db = BusterDb.OpenDatabase(dbName, userId, password)
  Dim dynaset = db.CreateDynaset(sql)

  Console.WriteLine("count = {0}", dynaset.RecordCount)

  While Not dynaset.EOF
    Console.WriteLine("name = {0}", dynaset("name").Value)
    Console.WriteLine("age = {0}", dynaset("age").Value)

    dynaset.MoveNext()
  Next

  dynaset.Close()
  db.Close()
End Using

ライセンス

zlib/libpng

oo4oを利用したコードとの比較は、次のテストコードを参照してください。

https://github.com/masaru-b-cl/Oo4oBuster/blob/master/Oo4oBuster.Test%2FOo4oBusterTest.vb

解説

ざっくりいえば、次のようなものがポイントです。

  • 動的アクセスを主体とする
    • VB6のころもVariant型でやってたし
    • ダイナセットの実装はプライベートで外に見せない
  • oo4oの基本的なAPIをエミュレートする
    • OpenDatabaseプロシージャ
    • CreateDynasetプロシージャ
    • Move*系プロシージャ
    • etc…
  • Disposableパターンで後処理する

実際業務で使ったのは、トランザクション管理などもう少しいろいろと実装していますが、基本はこんな感じです。

まとめ

動的アクセス万歳!

明日は…

@yajuさんにバトンタッチです。