読者です 読者をやめる 読者になる 読者になる

職業プログラマの休日出勤

職業プログラマによる日曜自宅プログラミングや思考実験の成果たち。リアル休日出勤が発生すると更新が滞りがちになる。記事の内容は個人の意見であり、所属している(いた)組織の意見ではない。

SQLFeatureNotSupportedException - JDBC4.0 API の中で未実装のもの

PostgreSQL Advent Calendar 2011 24日目の記事です。飛び入り参加しました。

この記事の主題はPostgreSQLJava言語向けクライアントインタフェースである、JDBC Driverです。「今さらJavaですか?」という声も聞こえてきそうですが、まだまだ多くの場所で使われていると思うので、敢て取り上げたいと思います。
2011年、「今年の漢字」として「絆」が選ばれたこともあり、PostgreSQLとプログラムとの絆を実現するドライバの話題は今年に相応しい、ですよね?

JDBC4.0

JDBCとは、Java言語環境から各種データベースへ接続するためのAPIです。各データベース製品は、このJDBCの仕様に従ってドライバを実装して提供することにより、Javaプログラムから簡単に接続してもらうことが可能になります。
このJDBCのバージョン4.0は2006年11月に仕様が確定しています。これから約5年が経過していますが、PostgreSQLJDBCドライバは >>Support for JDBC4 methods is not complete, but the majority of methods are implemented.<< (公式WebSiteより)という状態です。それでは具体的に何が未実装なのでしょうか?

未実装リスト

呼び出したJDBC APIが未実装であることを意味する例外 java.sql.SQLFeatureNotSupportedException を明示的に発生させているものの中から、よく使われそうなものをリストアップしてみました。「よく使われそうなもの」は筆者の独断と偏見です(笑)。
※調査対象は、version9.1 Build 901 JDBC Source

JDBCのクラス/インタフェース名 PostgreSQLでのクラス/インタフェース名 メソッド コメント
java.sql.Wrapper org.postgresql.ds.jdbc4. AbstractJdbc4PoolingDataSource isWrapperFor/unwrap そのオブジェクトがラッパか否かを判定します。複雑な処理をやる時は使いそうですね。その他データソース系のクラスでも同様。
java.sql.Blob org.postgresql.jdbc4. AbstractJdbc4Blog getBinaryStream(long, long) 区間を指定してInputStreamを取得する動作は未実装のようです。BLOB全体をInputStreamで取得する操作は以前からサポートされています。CLOBについても同様。
java.sql.Connection org.postgresql.jdbc4. AbstractJdbc4Connection createBlob() 空っぽのBLOBを作成する機能です。CLOBやNCLOBについても同様。現状はlo_create関数などを使うしか無いということですかね。
java.sql.Connection org.postgresql.jdbc4. AbstractJdbc4Connection getSchema() JDK1.7より。現在のスキーマ名を取得する機能です。
java.sql. ResultSet org.postgresql.jdbc4. AbstractJdbc4ResultSet updateBlob(int, InputStream) 結果セット上のBLOBをInputStreamの内容で更新する機能です。CLOBやNCLOBについても同様。
java.sql. PreparedStatement org.postgresql.jdbc4. AbstractJdbc4Statement setRowId PreparedStatementでのinsert/updateでRowIdをセットするための機能です。Javaで言うRowIdはPostgreSQLのoidのようなものでしょうか。oidをクライアント側で決定/変更するのは無理だったと思います。JDBCもそれに倣った形ですね。
java.sql. PreparedStatement org.postgresql.jdbc4. AbstractJdbc4Statement setBinaryStream PreparedStatementでのinsert/update1文でBLOBをセットするための機能です。CLOBやNCLOBについても同様。

ざっと、こんなところでしょうか。ラージオブジェクトを楽に使うために追加されたAPIは未実装が多いという印象です。また、当然ながら他にもいろいろあります。利用する際は気をつけたいものです。時間があれば実装にも挑戦してみたいなぁ等とも思います。

ついでに

いろいろ実験やってて思ったのですが、JDBC Driver が出力するエラーメッセージって、機械翻訳っぽい日本語が多いですよね。前述の未実装部分の実装と共に、より日本語っぽい表現に書き換えたいところです。日本国内でのPostgreSQL普及促進のためには、こちらの方が優先度が高いのかもしれません。

参考情報へのリンク

最後に

最終日:25日目を書いて下さる方、現時点でも募集中です。お早めに!