オレオレSQL関数の作り方〜HSQLDB編〜
Seasar Conference 2008 Autumnですべらない話、じゃなくてTeeda再考を話されるよねむらさん、じゃなくて米林さんの以下のエントリがきっかけになり、オレオレSQL関数の作り方〜HSQLDB編〜という事でHSQLDBに、自作のSQL関数を組み込むやり方を簡単にめもっときます。
といっても例によって積読状態の以下の本の11章を参考にしています。
Code Reading―オープンソースから学ぶソフトウェア開発技法
- 作者: トップスタジオ,まつもとゆきひろ,平林俊一,鵜飼文敏
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2004/06/01
- メディア: 単行本
- 購入: 18人 クリック: 550回
- この商品を含むブログ (214件) を見る
対象のバージョンは1.8.0.9です。本のほうはバージョン1.61ですね。
追加する関数は、世界のナベアツの【3の倍数と3がつく数字の時だけアホになる】関数です(笑)。
まずいじるソースは、org.hsqldb.Libraryのみです。
sNumericという関数名とメソッド名の2次元配列があります。
public static final String[][] sNumeric = { { "ABS", "org.hsqldb.Library.abs" }, { "ACOS", "java.lang.Math.acos" }, { "ASIN", "java.lang.Math.asin" ...
ABSという関数の実態はorg.hsqldb.Library#absメソッドです。org.hsqldb.Library#absメソッドは下記のとおり。
public static double abs(double d) { return Math.abs(d); }
これを参考にnabeatsu関数を追加します。
}, { "ROUNDMAGIC", "org.hsqldb.Library.roundMagic" }, { "NABEATSU", "org.hsqldb.Library.nabeatsu" } };
public static String nabeatsu(int i) { if(i%3 == 0) { return "アホ"; } else if(String.valueOf(i).indexOf("3") != -1) { return "アホ"; } else { return null; } }
とします。
また関数に対応するint型のキーを登録します。これもabsを真似てnabeatsuを67で登録します。
static final int abs = 0; ... static final int year = 66; static final int nabeatsu = 67; /** @todo see bitxor and datediff numbering */ // private static final IntValueHashMap functionMap = new IntValueHashMap(68); static final Double piValue = new Double(Library.pi()); static { functionMap.put("abs", abs); functionMap.put("ascii", ascii); ... functionMap.put("nabeatsu", nabeatsu); }
このキーがswitchで回ってくるので対応するcaseを追加します。これも他を真似る。
static Object invoke(int fID, Object[] params) throws HsqlException { try { switch (fID) { case abs : { return new Double( Library.abs(((Number) params[0]).doubleValue())); } ... case nabeatsu : { return nabeatsu(((Number) params[0]).intValue()); } ...
全体のdiffは以下のとおり。
182a183,184 > }, { > "NABEATSU", "org.hsqldb.Library.nabeatsu" 443a446,455 > > public static String nabeatsu(int i) { > if(i%3 == 0) { > return "アホ"; > } else if(String.valueOf(i).indexOf("3") != -1) { > return "アホ"; > } else { > return null; > } > } 1945a1958 > static final int nabeatsu = 67; 1951c1964 < new IntValueHashMap(67);
-
- -
ビルドして、
create table test(i int);
insert into test values(1);
select NABEATSU(3) from test;
と実行すると下記のようになる。