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 org.opengion.fukurou.util.AbstractObjectPool;
019import org.opengion.fukurou.system.Closer;
020import org.opengion.fukurou.system.OgRuntimeException ;                         // 6.4.2.0 (2016/01/29)
021import static org.opengion.fukurou.system.HybsConst.CR;                         // 6.1.0.0 (2014/12/26) refactoring
022import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;      // 6.4.3.3 (2016/03/04)
023
024import java.util.concurrent.ConcurrentMap;                                                      // 6.4.3.3 (2016/03/04)
025import java.util.concurrent.ConcurrentHashMap;
026import java.util.Locale;
027import java.util.Properties;
028import java.sql.Connection;
029import java.sql.SQLException;
030import java.sql.DriverManager;
031import java.sql.DatabaseMetaData;
032
033/**
034 * データベースのコネクションオブジェクトを取得する為に使用する,ファクトリクラスです。
035 *
036 * Connection.connection() メソッドで,Connectionオブジェクトを取得します。
037 * Connection#close() メソッドで,内部的に ConnectionFactory にオブジェクトを戻す
038 * 事によって,Connectionオブジェクトのプーリングを行なっています。
039 *
040 * コネクションオブジェクトは,プールから貸し出します。
041 * つまり,貸し出し中には,プールには,オブジェクトは残っていません。
042 * その状態で,コネクションオブジェクトをclose()しない場合は,オブジェクトが破棄されて,
043 * 貸し出し中カウントと実際のオブジェクト数が食い違い,リソースが不足します。
044 * 必ず,作成したオブジェクトは,close()メソッドを呼び出して,プールに返して下さい。
045 *
046 * システムリソースの USE_DB_APPLICATION_INFO=true の場合、コネクションにアプリケーション
047 * 情報を追記するため、ApplicationInfoオブジェクトを使用します。
048 * このオブジェクトは、jsp/common/session-init.jsp にてユーザー情報とアプリケーション
049 * 情報を画面アクセスごとに設定します。
050 *
051 * @og.group DB/Shell制御
052 * @og.rev 4.0.0.0 (2007/10/16) パッケージ移動(hayabusa/db ⇒ fukurou/db)
053 *
054 * @version  4.0
055 * @author   Kazuhiko Hasegawa
056 * @since    JDK5.0,
057 */
058public final class ConnectionFactory {
059        /** 6.4.3.4 (2016/03/11) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 */
060        private static final ConcurrentMap<String,ConnectionPool> CONN_MAP = new ConcurrentHashMap<>();
061
062        // 4.0.0.0 (2007/10/10) キャッシュされた、初期ConnectionPool を使用
063        // 4.0.0.0 (2007/10/29) 初期値をここでセットする
064        private static String                   defDBID = "DEFAULT";                                    // 6.3.9.1 (2015/11/27) Variables should start with a lowercase character(PMD)
065        private static ConnectionPool   defPOOL ;                                                               // 6.3.9.1 (2015/11/27) Variables should start with a lowercase character(PMD)
066        private static DatabaseConfig   dbConf ;
067
068        /**
069         *  デフォルトコンストラクターをprivateにして、
070         *  オブジェクトの生成をさせないようにする。
071         *
072         */
073        private ConnectionFactory() {
074                // オブジェクトの生成をさせないようにする。
075        }
076
077        /**
078         * 初期化メソッドです。
079         * <pre>
080         * 1)第二引数にXMLファイルをクラスローダ基底からの相対パスで指定した場合は
081         *   そのXMLを利用してDBConfigオブジェクトを作成します。例:ConnectionFactory.init( CONTEXT_NAME, "../DBConfig.xml")
082         *   nullの場合はWEB-INF/DBConfig.xmlを利用します。例:ConnectionFactory.init( CONTEXT_NAME, null)
083         * 2)キャッシュ初期ConnectionPoolのキーを設定してキャッシュプールを作ります。
084         *   この値がnullの場合は"DEFAULT"が設定されます。
085         * </pre>
086         * 
087         * <strong>このクラスを利用する場合は必ず最初にこのメソッドを実行する必要があります。</strong>
088         * キャッシュとDBConfigオブジェクトの同期化はされていないので初期化以外での利用は避けて下さい。
089         *
090         * @og.rev 4.0.0.0 (2007/11/05) 新規作成
091         * @og.rev 6.4.3.3 (2016/03/04) DatabaseConfig のコンストラクター修正で、引数の nullチェックは不要。
092         *
093         * @param defPoolKey  初期DBID名(nullの場合は、"DEFAULT")
094         * @param xmlFileName DBConfig.xmlファイルのファイル名(nullの場合は、WEB-INF/DBConfig.xml)
095         */
096        public static void init( final String defPoolKey, final String xmlFileName ) {
097                // DBConfigオブジェクトの作成
098                // 6.4.3.3 (2016/03/04) DatabaseConfig のコンストラクター修正で、引数の nullチェックは不要。
099                dbConf = new DatabaseConfig( xmlFileName );
100
101                if( defPoolKey == null || defPoolKey.isEmpty() || dbConf.getDbid( defPoolKey ) == null ) {
102                        defDBID = "DEFAULT";
103                }
104                else {
105                        defDBID = defPoolKey;
106                }
107                final EDbid edbid = dbConf.getDbid( defDBID );
108                if( edbid == null ) {
109                        final String errMsg = "初期化時に、指定のDBIDキーが存在しません。"
110                                + "[Key ="
111                                + defDBID
112                                + "]";
113                        throw new OgRuntimeException( errMsg );
114                }
115
116        //      if( DEF_POOL != null ) { DEF_POOL.clear(); }    // 6.0.2.5 (2014/10/31) nullでなければ初期化する。
117                defPOOL = new ConnectionPool( edbid );
118        }
119
120        /**
121         * コネクションオブジェクトを取得します。
122         * 遅い初期化を行なう事により,実際に必要となるまでコネクションオブジェクトは
123         * 作成しません。
124         * 最大プール数に達して,なおかつ,すべてのConnectionが貸し出し中の場合,
125         *
126         * @og.rev 2.1.1.3 (2002/11/22) コネクションID が null の場合に DEFAULT から所得するように変更。
127         * @og.rev 3.1.0.0 (2003/03/20) Hashtable を使用している箇所で、非同期でも構わない箇所を、HashMap に置換え。
128         * @og.rev 3.5.6.2 (2004/07/05) 文字列の連結にStringBuilderを使用します。
129         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
130         * @og.rev 3.8.8.2 (2007/01/26) USE_DB_APPLICATION_INFO ⇒ pool.useApplicationInfo() 変更
131         * @og.rev 4.0.0.0 (2007/10/10) キャッシュされた、初期ConnectionPool を使用
132         * @og.rev 4.1.0.1 (2008/01/21) 登録時に、大文字に変換する。
133         * @og.rev 6.4.3.3 (2016/03/04) Map#computeIfAbsent で対応する。
134         *
135         * @param   dbid 接続先ID
136         * @param   appInfo アプリ情報オブジェクト
137         *
138         * @return  コネクションオブジェクト
139         */
140        public static Connection connection( final String dbid , final ApplicationInfo appInfo ) {
141                final ConnectionPool pool ;
142                if( dbid == null || dbid.isEmpty() || defDBID.equalsIgnoreCase( dbid ) ) {
143                        pool = defPOOL ;
144                }
145                else {
146                        final String udbid = dbid.toUpperCase( Locale.JAPAN );  // 大文字化
147
148                        // 6.4.3.3 (2016/03/04) Map#computeIfAbsent で対応する。
149                        // Map#computeIfAbsent : 戻り値は、既存の、または計算された値。追加有り、置換なし、削除なし
150                        // ※ 注意:ConnectionPool のコンストラクタに、従来と異なり、DatabaseConfig オブジェクトを渡しています。
151                        pool = CONN_MAP.computeIfAbsent( udbid , k -> new ConnectionPool( dbConf,udbid ) );
152
153                }
154
155                final Connection conn = pool.newInstance();
156
157                // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを使用
158                // 3.8.8.2 (2007/01/26) ORACLE 以外は、使用しません。
159                // 4.0.0.0 (2007/11/29) 入れ子if の統合
160                if( appInfo != null && pool.useApplicationInfo() ) {
161                        appInfo.callAppInfo( conn );
162                }
163                return conn;
164        }
165
166        /**
167         * コネクションオブジェクトをプールに戻します。
168         * Connectionオブジェクトは,close()メソッドで,自分自身を ConnectionFactory の
169         * プールに戻します。
170         * それ以外の コネクションオブジェクトをプールに戻す場合は,このメソッドを使用します。
171         *
172         * @og.rev 2.1.1.3 (2002/11/22) コネクションID が null の場合に DEFAULT から所得するように変更。
173         * @og.rev 4.0.0.0 (2007/10/10) キャッシュされた、初期ConnectionPool を使用
174         * @og.rev 4.1.0.1 (2008/01/21) 登録時に、大文字に変換する。
175         *
176         * @param   conn コネクションオブジェクト
177         * @param   dbid 接続先ID
178         */
179        public static void close( final Connection conn,final String dbid ) {
180                if( conn != null ) {
181                        if( dbid == null || dbid.isEmpty() || defDBID.equalsIgnoreCase( dbid ) ) {
182                                defPOOL.release( conn ) ;
183                        }
184                        else {
185                                final String udbid = dbid.toUpperCase( Locale.JAPAN );  // 大文字化
186        //                      synchronized( CONN_MAP ) {
187                                        final ConnectionPool pool = CONN_MAP.get( udbid );
188                                        if( pool != null ) {
189                                                pool.release( conn );
190                                        }
191        //                      }
192                        }
193                }
194        }
195
196        /**
197         * コネクションオブジェクトを物理的に削除(クローズ)戻します。
198         * これは、コネクション等がエラーを起こした場合に、プールに戻すのではなく、
199         * 接続を閉じる場合に、使用されます。
200         *
201         * @og.rev 2.1.1.3 (2002/11/22) コネクションID が null の場合に DEFAULT から所得するように変更。
202         * @og.rev 4.0.0.0 (2007/10/10) キャッシュされた、初期ConnectionPool を使用
203         * @og.rev 4.1.0.1 (2008/01/21) 登録時に、大文字に変換する。
204         *
205         * @param   conn コネクションオブジェクト
206         * @param   dbid 接続先ID
207         */
208        public static void remove( final Connection conn,final String dbid ) {
209                if( conn != null ) {
210                        if( dbid == null || dbid.isEmpty() || defDBID.equalsIgnoreCase( dbid ) ) {
211                                defPOOL.remove( conn ) ;
212                        }
213                        else {
214                                final String udbid = dbid.toUpperCase( Locale.JAPAN );  // 大文字化
215                //              synchronized( CONN_MAP ) {
216                                        final ConnectionPool pool = CONN_MAP.get( udbid );
217                                        if( pool != null ) {
218                                                pool.remove( conn );
219                                        }
220                //              }
221                        }
222                }
223        }
224
225        /**
226         * コネクションオブジェクトを実際にすべてクローズします。
227         * コネクションプールの再編成や,管理者による強制クローズに使用します。
228         *
229         * クローズに失敗(コネクションが貸し出し中)の場合は,内部的に
230         * DB_CLOSE_RETRY_TIME だけ待機して, DB_CLOSE_RETRY_COUNT 回数だけ,試行します。
231         * それでもクローズできない場合は, RuntimeException を throw します。
232         *
233         * @og.rev 4.0.0.0 (2005/01/31) ロジック見直し。 pool.clear() で、基本的にはすべて削除されます。
234         * @og.rev 4.0.0.0 (2007/10/10) キャッシュされた、初期ConnectionPool を使用
235         * @og.rev 6.4.3.3 (2016/03/04) Map#forEach で対応する。
236         */
237        public static void realClose() {
238                synchronized( defPOOL ) {
239                        if( ! defPOOL.isEmpty() ) {
240                                defPOOL.clear();
241                        }
242                }
243
244                // 6.4.3.3 (2016/03/04) Map#forEach で対応する。
245                CONN_MAP.forEach( (id,pl) -> pl.clear() );
246                CONN_MAP.clear();
247
248        }
249
250        /**
251         * ConnectionFactory の現在の状況(詳細メッセージ)を返します。
252         * これは,コネクションプールの数(最大値,作成済み数など)を確認する為のものです。
253         *
254         * @og.rev 4.0.0.0 (2007/10/10) キャッシュされた、初期ConnectionPool を使用
255         *
256         * @return  現在の状態表示
257         * @og.rtnNotNull
258         */
259        public static String information() {
260                return information( true );
261        }
262
263        /**
264         * ConnectionFactory の現在の状況を返します。
265         * これは,コネクションプールの数(最大値,作成済み数など)を確認する為のものです。
266         * 引数により詳細メッセージかどうかを指定できます。
267         *
268         * @og.rev 4.0.0.0 (2007/10/10) キャッシュされた、初期ConnectionPool を使用
269         * @og.rev 5.3.4.0 (2011/04/01) 詳細メッセージ用引数を追加
270         * @og.rev 5.6.7.3 (2013/08/23) 若干の修正
271         * @og.rev 6.4.3.3 (2016/03/04) Map#forEach で対応する。
272         *
273         * @param       isDetail        詳細メッセージかどうか [true:詳細メッセージ/false:簡易メッセージ]
274         *
275         * @return  現在の状態表示
276         * @og.rtnNotNull
277         */
278        public static String information(final boolean isDetail ) {
279                // 4.0.0.0 (2007/10/25) hybsとの依存関係を弱めるため。
280                final StringBuilder strBuf = new StringBuilder( BUFFER_MIDDLE );
281
282                strBuf.append( "<b>【Connection Information】</b>" ).append( CR );        // 5.6.7.3 (2013/08/23) 若干の修正
283
284                synchronized( defPOOL ) {
285                        if( ! defPOOL.isEmpty() ) {
286                                // 5.3.4.0 (2011/04/01) 詳細メッセージ用引数を追加
287                                if( isDetail ) {
288                                        strBuf.append( defPOOL.toString() ).append( "<br /><hr />" );
289                                }
290                                else {
291                                        strBuf.append( defPOOL.dbidInfo() );
292                                }
293                        }
294                }
295
296                // 6.4.3.3 (2016/03/04) Map#forEach で対応する。
297                CONN_MAP.forEach( (id,pl) -> {
298                                if( isDetail ) {
299                                        strBuf.append( pl.toString() ).append( "<br /><hr />" );
300                                }
301                                else {
302                                        strBuf.append( pl.dbidInfo() );
303                                }
304                        }
305                );
306
307                return strBuf.append( CR ).toString();
308
309        }
310
311        /**
312         * この接続が、PreparedStatement#getParameterMetaData() を使用するかどうかを判定します。
313         *
314         * PreparedStatement に対して、String化された 数字などを setObject( int,String ) するとき、
315         * ORACLE と SQLServer は、そのまま設定すれば、自動的に変換されます。
316         * postgreSQL では、ParameterMetaData#getParameterType(int) で、カラムタイプを取得し、
317         * setObject( int,String,int ) する必要があります。
318         * その判定に、このメソッドを使用します。
319         * この結果は、あくまで、各種データベース毎の実地調査の結果を元に、判定結果を
320         * 返すようにしています。
321         * ORACLE の場合は、使用しない(false)が返るように設定しています。
322         * SQLServer では、ORACLEと同様に、false を返します。
323         *
324         * このメソッドは、元々、ApplicationInfo#useParameterMetaData(Connection) に有ったものを
325         * EDbid から取得するように修正したものです。
326         *
327         * @og.rev 5.3.8.0 (2011/08/01) 新規追加
328         * @og.rev 6.4.3.3 (2016/03/04) EDbid のnullチェックを追加
329         *
330         * @param dbid 接続先ID
331         *
332         * @return      [true:使用する/false:その他]
333         */
334        public static boolean useParameterMetaData( final String dbid ) {
335
336                // 6.1.0.0 (2014/12/26) refactoring の一環
337                final String udbid = dbid == null || dbid.isEmpty() ? defDBID : dbid.toUpperCase( Locale.JAPAN ) ;              // 6.4.2.1 (2016/02/05) PMD refactoring. Useless parentheses.
338
339                final EDbid edbid = dbConf.getDbid( udbid );
340
341                return edbid != null && edbid.useParamMetaData();
342        }
343
344        /**
345         * 接続先のDB名に対応した、enum (DBName) を返します(toUpperCase)。
346         *
347         * @og.rev 5.1.4.0 (2010/03/01) getDBFullName の代わりに新規作成
348         * @og.rev 5.7.7.2 (2014/06/20) 最初の取得時のエラー回避
349         *
350         * @param dbid 接続先ID
351         *
352         * @return  接続先のDB名
353         * @og.rtnNotNull
354         */
355        public static String getDBName( final String dbid ) {
356                final String dbName;
357
358                if( dbid == null || dbid.isEmpty() || defDBID.equalsIgnoreCase( dbid ) ) {
359                        dbName = defPOOL.getDBName();
360                }
361                else {
362                        final String udbid = dbid.toUpperCase( Locale.JAPAN );  // 大文字化
363                        ConnectionPool pool = null;
364        //              synchronized( CONN_MAP ) {
365                                pool = CONN_MAP.get( udbid );
366                                if( pool == null ) {
367                                        connection( dbid, null );               // ダミーで、コネクトする。
368                                        pool = CONN_MAP.get( udbid );   // connectionで、CONN_MAP に設定しているため、もう一度、取得する。
369                                }
370        //              }
371                        // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
372                        if( pool == null ) {
373                                final String errMsg = "指定のDBIDキーに対応するデータベース名を取得出来ません。"
374                                                                        + "[Key =" + dbid + "]";
375                                throw new OgRuntimeException( errMsg );
376                        }
377
378                                dbName = pool.getDBName();
379                }
380
381                return dbName.toUpperCase( Locale.JAPAN );
382        }
383
384        /**
385         * ConnectionPool は、AbstractObjectPool を継承した オブジェクトプールです。
386         *
387         * コネクションオブジェクトをプールすることにより、ConnectionFactory で
388         * 管理する Map オブジェクトの実態として、各ID毎の コネクションをキープします。
389         *
390         * @og.group DB/Shell制御
391         *
392         * @version  4.0
393         * @author   Kazuhiko Hasegawa
394         * @since    JDK5.0,
395         */
396        // class ConnectionPool extends AbstractObjectPool<Connection> {
397        private static final class ConnectionPool extends AbstractObjectPool<Connection> {
398                private final transient EDbid edbid;
399
400                /**
401                 * DatabaseConfig と、dbid を指定して作成する コンストラクター
402                 * オブジェクト作成時のMap設定で、一連の処理を行うために、エラーチェックをもつ
403                 * コンストラクターを用意します。
404                 * DBID が null の場合は,"DEFAULT" が使用されます。
405                 *
406                 * @og.rev 6.4.3.3 (2016/03/04) 処理の簡素化のための新規コンストラクター追加
407                 *
408                 * @param   dbConf      DatabaseConfigオブジェクト
409                 * @param   dbid        接続先ID(大文字に変換済み)
410                 */
411                private ConnectionPool( final DatabaseConfig dbConf , final String dbid ) {
412                        super();
413
414                        final EDbid edbid = dbConf.getDbid( dbid );
415                        if( edbid == null ) {
416                                final String errMsg = "指定のDBIDキーが存在しません。"
417                                        + "[Key ="
418                                        + dbid
419                                        + "]";
420                                throw new OgRuntimeException( errMsg );
421                        }
422
423                        this.edbid      =       edbid;
424                        init( edbid.getMincount(),edbid.getMaxcount(),true,edbid.getPooltime() );
425                }
426
427                /**
428                 * DBID を指定して作成する コンストラクター
429                 * DBID をキーに、 HybsSystem.sys メソッドのデータベース変数を取得します。
430                 * 取得するのは、 DBID + _DB_URL/_DB_USER/_DB_PASSWD/_DB_MINCOUNT/_DB_MAXCOUNT
431                 * です。
432                 * DBID が null の場合は,"DEFAULT" が使用されます。
433                 *
434                 * @og.rev 3.5.4.3 (2004/01/05) キャッシュの寿命を指定
435                 * @og.rev 3.5.4.7 (2004/02/06) DBID のゼロストリングチェック追加
436                 * @og.rev 4.0.0.0 (2007/10/10) キャッシュされた、初期ConnectionPool を使用
437                 * @og.rev 4.0.0.0 (2007/10/25) DB設定情報のXML化に伴う変更
438                 * @og.rev 6.4.1.1 (2016/01/16) PMD refactoring. It is a good practice to call super() in a constructor
439                 *
440                 * @param   edbid 接続先情報オブジェクト
441                 */
442                public ConnectionPool( final EDbid edbid ) {
443                        super();
444
445                        // 4.0.0.0 XML化に伴いロード先を変更
446                        this.edbid      =       edbid;
447                        init( edbid.getMincount(),edbid.getMaxcount(),true,edbid.getPooltime() );
448                }
449
450                /**
451                 * オブジェクトプールから削除するときに呼ばれます。
452                 * このメソッドで各オブジェクトごとの終了処理を行います。
453                 * 例えば、データベースコネクションであれば、close() 処理などです。
454                 *
455                 * @og.rev 3.5.4.8 (2004/02/23) SQLException は無視します。
456                 * @og.rev 3.5.6.0 (2004/06/18) synchronized を解除します。
457                 *
458                 * @param  obj 終了処理を行うオブジェクト
459                 */
460                @Override
461                protected void objectFinal( final Connection obj ) {
462                        Closer.connClose( obj );
463                }
464
465                /**
466                 * コネクションオブジェクトを作成します。
467                 * DriverManager.getConnection により作成されたConnection を Connection で
468                 * ラッピングします。
469                 * Connectionオブジェクトは,close()メソッドで,自分自身を ConnectionFactory の
470                 * プールに戻します。
471                 *
472                 * @og.rev 3.3.3.3 (2003/08/06) コネクションに対して、setTransactionIsolation を、設定しておく。
473                 * @og.rev 3.5.2.0 (2003/10/20) 接続情報に、データベース名、ドライバ名情報を追加する。
474                 * @og.rev 3.5.6.0 (2004/06/18) synchronized を解除します。
475                 * @og.rev 3.8.8.2 (2007/01/26) useAppInfo を設定します。
476                 * @og.rev 4.0.0.0 (2007/10/30) 保持情報オブジェクト化に伴う変更
477                 * @og.rev 5.1.2.0 (2010/01/01) MySQL対応 明示的に、TRANSACTION_READ_COMMITTED を指定する。
478                 * @og.rev 5.5.2.0 (2012/05/01) properties対応
479                 * @og.rev 6.3.9.0 (2015/11/06) 内部Propertiesオブジェクトではなく、複製して返します。
480                 *
481                 * @return  コネクションオブジェクト
482                 */
483                @Override
484                protected Connection createInstance() {
485                        Connection conn = null;
486                        try {
487                //              DriverManager.setLogWriter( HybsSystem.out );                   // ドライバーのログ
488
489                                // 5.5.2.0 (2012/05/01) propertyの追加処理と、接続のproperties化
490                                // 6.3.9.0 (2015/11/06) 内部Propertiesオブジェクトではなく、複製して返します。
491        //                      final Properties prop = new Properties (edbid.getProps());
492                                final Properties prop = edbid.getProps();
493                                prop.put ( "user"    , edbid.getUser() );
494                                prop.put ( "password", edbid.getPassword() );
495
496                                conn = DriverManager.getConnection( edbid.getUrl(), prop );
497                //              conn.setReadOnly( true );
498                                conn.setReadOnly( edbid.isReadonly() );
499
500                                conn.setAutoCommit( false );
501                                conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);  // 初期値
502                //              ((OracleConnection)conn).setDefaultExecuteBatch(1);  // 初期値
503                //              ((OracleConnection)conn).setDefaultRowPrefetch(20);  // 初期値
504
505                                // 3.5.2.0 (2003/10/20) 接続情報に、データベース名、ドライバ名情報を追加する。
506                                // 4.0.0.0 (2007/10/26) 登録先をオブジェクト化
507                                if( edbid.getDbProductName() == null ) {
508                                        final DatabaseMetaData meta = conn.getMetaData();
509                                        edbid.setMetaDataInfo( meta );
510                                }
511                                return conn ;
512                        }
513                        catch( final SQLException ex ) {
514                                final String errMsg = "コネクトすることが出来ません。" + CR
515                                                                + "DBID=[" + edbid.getDbidKey() + "]"   + CR
516                                                                + ex.getMessage() + " , status=" + ex.getSQLState();
517                                Closer.connClose( conn );
518                                throw new OgRuntimeException( errMsg,ex );              // 3.5.5.4 (2004/04/15) 引数の並び順変更
519                        }
520                }
521
522                /**
523                 * アクセスログ取得の為のDBMS_APPLICATION_INFOの使用可否を取得します(初期値:true)。
524                 *
525                 * データベースへのアクセスログ取得の為、エンジンで接続するコネクションについて
526                 * DBMS_APPLICATION_INFO.SET_CLIENT_INFO と SET_MODULE を呼び出しています。
527                 * この処理は、ORACLEとの接続のみ有効ですので、接続先データベースが ORACLE 以外は
528                 * false を返します。
529                 * ORACLE の場合は、システムリソースの USE_DB_APPLICATION_INFO 属性の設定値を
530                 * 返します。
531                 * この設定値の初期値は、true です。
532                 *
533                 * @og.rev 3.8.8.2 (2007/01/26) 新規追加
534                 *
535                 * @return  true:使用する/false:使用しない
536                 */
537                public boolean useApplicationInfo() {
538                        return edbid.isApplicationInfo();
539                }
540
541                /**
542                 * 接続先のDB名を返します。
543                 *
544                 * @og.rev 4.3.7.0 (2009/06/01) 新規作成
545                 *
546                 * @return  接続先のDB名
547                 */
548                public String getDBName() {
549                        return edbid.getDbProductName();
550                }
551
552                /**
553                 * 接続先のDBバージョンを返します。
554                 *
555                 * @og.rev 4.3.7.0 (2009/06/01) 新規作成
556                 *
557                 * @return 接続先のDBバージョン
558                 */
559                public String getDBVersion() {
560                        return edbid.getDbProductVersion();
561                }
562
563                /**
564                 * 接続先の簡易な内部情報を返します。
565                 *
566                 * @og.rev 5.3.4.0 (2011/04/01) toString() の簡易版
567                 *
568                 * @return 接続先の簡易な内部情報
569                 */
570                public String dbidInfo() {
571                        return edbid.info();
572                }
573
574                /**
575                 * 内部状況を簡易的に表現した文字列を返します。
576                 * DBID/URL/USER/プールサイズ を返します。
577                 *
578                 * @og.rev 3.5.2.0 (2003/10/20) 接続情報に、データベース名、ドライバ名情報を追加する。
579                 * @og.rev 3.5.6.6 (2004/08/23) 同期化方法を統一する為、synchronized をつけます。(別途 要検討)
580                 * @og.rev 4.0.0.0 (2007/10/29) EDbidのtoStringを呼ぶように変更
581                 *
582                 * @return   このオブジェクトプールの文字列表現
583                 * @og.rtnNotNull
584                 */
585                @Override
586                public String toString() {
587                        return edbid.toString() + super.toString() ;
588                }
589        }
590}