001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.fukurou.db; 017 018import java.util.Locale; 019 020/** 021 * 各データベースに対応するenum名を返します。 022 * 主に、各データベースにおける関数名の差異を吸収するためのenumです。 023 * 本来は、互換性のあるファンクション以外、使用しないようにしましょう。 024 * また、無ければ互換性パックなどで、ファンクションを定義してしまうのも 025 * 一つの方法です。 026 * 027 * <table border="1" frame="box" rules="all" > 028 * <caption>各データベースにおける関数</caption> 029 * <tr><th>データベース名 </th><th>連結</th><th>部分文字列</th></tr> 030 * <tr><td>{@DBF.XXX}</td><td>CON </td><td>SUBSTR </td></tr> 031 * <tr><td>ORACLE </td><td>|| </td><td>SUBSTR </td></tr> 032 * <tr><td>HSQL </td><td>|| </td><td>SUBSTR </td></tr> 033 * <tr><td>POSTGRES </td><td>|| </td><td>SUBSTR </td></tr> 034 * <tr><td>MYSQL </td><td>|| </td><td>SUBSTR </td></tr> 035 * <tr><td>SQLSERVER </td><td>+ </td><td>SUBSTRING </td></tr> 036 * <tr><td>FIREBIRD </td><td>|| </td><td>SUBSTR </td></tr> 037 * <tr><td>CACHE </td><td>|| </td><td>SUBSTRING </td></tr> 038 * </table> 039 * 040 * @og.rev 5.1.4.0 (2010/03/01) 新規作成 041 * @og.rev 5.8.5.0 (2015/03/06) CACHE追加 042 * 043 * @version 5.0 044 * @author Kazuhiko Hasegawa 045 * @since JDK5.0, 046 */ 047public enum DBFunctionName { 048 // 引数付きenum定義:ここに、必要な関数が増えるたびに、追加していきます。 049 // CON SUBSTR 050 ORACLE ( "||","SUBSTR" ) 051 , HSQL ( "||","SUBSTR" ) 052 , POSTGRES ( "||","SUBSTR" ) 053 , MYSQL ( "||","SUBSTR" ) 054 , SQLSERVER ( "+" ,"SUBSTRING" ) 055 , FIREBIRD ( "||","SUBSTR" ) 056 , CACHE ( "||","SUBSTRING" ) ; 057 058 private final String dbfCON ; 059 private final String dbfSUBSTR ; 060 061 /** 062 * コンストラクター(enum の場合は、private宣言される) 063 * 064 * @og.rev 5.1.4.0 (2010/03/01) 新規作成 065 * 066 * @param con 第一引数にて指定(CON) 067 * @param substr 第一引数にて指定(SUBSTR) 068 */ 069 private DBFunctionName( final String con , final String substr ) { 070 dbfCON = con; 071 dbfSUBSTR = substr; 072 } 073 074 /** 075 * 共通ファンクションに対応するデータベース個別のファンクション名を返します。 076 * 077 * 現時点では、NAME,CON,SUBSTR のみ使用できます。 078 * 079 * 080 * @og.rev 5.1.4.0 (2010/03/01) 新規作成 081 * 082 * @param func 共通ファンクション 083 * 084 * @return ファンクション名 085 */ 086 public String getFunctionName( final String func ) { 087 if( "NAME".equals( func ) ) { return toString(); } 088 if( "CON".equals( func ) ) { return dbfCON; } 089 if( "SUBSTR".equals( func ) ) { return dbfSUBSTR; } 090 091 return func; 092 } 093 094 /** 095 * シーケンス名よりシーケンスオブジェクトを検索し、次の値を取り出します。 096 * DBに対するシーケンスオブジェクトは予め作成されている必要があります。 097 * 098 * また、MySQLの場合は、シーケンスオブジェクトが実装されていないため、 099 * 内部的には、引数のシーケンス名と同じ名前のテーブルから、Integer型の 100 * "SEQID"という項目名を検索することにより、シーケンスをエミュレートしています。 101 * 102 * @og.rev 5.1.9.0 (2010/08/01) 新規追加 103 * @og.rev 5.8.5.0 (2015/03/06) CACHE追加 104 * 105 * @param seqName シーケンス名 106 * @param tran トランザクション 107 * 108 * @return シーケンス番号 109 */ 110 public int getSequence( final String seqName, final Transaction tran ) { 111 String sql = null; 112 String[][] rtn = null; 113 switch ( this ) { 114 case ORACLE: 115 sql = "select " + seqName + ".nextval from dual"; 116 break; 117 case HSQL: 118 sql = "select next value for " + seqName + " from dual"; 119 break; 120 case POSTGRES: 121 sql = "select nextval('" + seqName + "')"; 122 break; 123 case MYSQL: 124 sql = "update " + seqName + " set SEQID = last_insert_id(SEQID+1)"; 125 DBUtil.dbExecute( sql, new String[0], tran ); 126 sql = "select last_insert_id()"; 127 break; 128 case SQLSERVER: 129 throw new RuntimeException( "現在、SQLSERVERではシーケンス機能はサポートされていません。" ); 130 case FIREBIRD: 131 sql = "select gen_id(" + seqName + ", 1) from rdb$database"; 132 break; 133 case CACHE: 134 throw new RuntimeException( "現在、CACHEではシーケンス機能はサポートされていません。" ); 135 default: 136 throw new RuntimeException( "現在、このデータベースではシーケンス機能はサポートされていません。" ); 137 } 138 139 rtn = DBUtil.dbExecute( sql, new String[0], tran ); 140 return Integer.valueOf( rtn[0][0] ); 141 } 142 143 /** 144 * 各データベースに対応するenum名を返します。 145 * 146 * @og.rev 5.1.4.0 (2010/03/01) 新規作成 147 * @og.rev 5.8.5.0 (2015/03/06) CACHE追加 148 * @og.rev 5.9.19.0 (2017/04/07) Azure対応。基本的にFunction等はDB種別に依存するはず。 149 * 150 * @param dbName データベース名 151 * 152 * @return データベースに対応するenum名 153 */ 154 public static DBFunctionName getDBName( final String dbName ) { 155// String dbn = dbName.toUpperCase( Locale.JAPAN ); 156 String dbn = DBUtil.getDBType(dbName).toUpperCase( Locale.JAPAN ); 157 158 if( dbn.indexOf( "ORACLE" ) >= 0 ) { return DBFunctionName.ORACLE; } 159 else if( dbn.indexOf( "HSQL" ) >= 0 ) { return DBFunctionName.HSQL; } 160 else if( dbn.indexOf( "POSTGRES" ) >= 0 ) { return DBFunctionName.POSTGRES; } 161 else if( dbn.indexOf( "MYSQL" ) >= 0 ) { return DBFunctionName.MYSQL; } 162 else if( dbn.indexOf( "SQLSERVER" ) >= 0 ) { return DBFunctionName.SQLSERVER; } 163 else if( dbn.indexOf( "FIREBIRD" ) >= 0 ) { return DBFunctionName.FIREBIRD; } 164 else if( dbn.indexOf( "CACHE" ) >= 0 ) { return DBFunctionName.CACHE; } 165 166 final String errMsg = "初期化時に、指定の dbName キーが存在しません。" 167 + "[" + dbn + "]" ; 168 169 throw new RuntimeException( errMsg ); 170 } 171 172 /** 173 * 各データベースに対応するファンクション名を返します。 174 * 175 * @og.rev 4.3.8.0 (2009/08/01) SUBSTRを追加 176 * @og.rev 5.1.2.0 (2010/01/01) MySQL対応,SUBSTRB廃止(帳票データの分割の内部処理化に伴う) 177 * @og.rev 5.1.4.0 (2010/03/01) データベース名 ではなく、dbid で判断するように変更 178 * @og.rev 5.7.7.2 (2014/06/20) DBF.NAME 時の処理の簡素化 179 * @og.rev 5.9.19.1 (2017/04/14) DBF.TYPE追加 180 * 181 * @param func ファンクション名(定義文字) 182 * @param dbid 接続先ID 183 * 184 * @return 実ファンクション名 185 */ 186 public static String getFunctionName( final String func ,final String dbid ) { 187// DBFunctionName dbName = DBFunctionName.getDBName( ConnectionFactory.getDBName( dbid ) ); 188 189 // 5.7.7.2 (2014/06/20) DBF.NAME 時の処理の簡素化 190 String dbName = ConnectionFactory.getDBName( dbid ); 191 if( "NAME".equals( func ) ) { return dbName; } 192 else if( "TYPE".equals( func ) ){ return DBUtil.getDBType(dbName); } 193 else { 194 return getDBName( dbName ).getFunctionName( func ); 195 } 196 197// return dbName.getFunctionName( func ); 198 } 199}