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     */
016    package org.opengion.fukurou.db;
017    
018    import org.opengion.fukurou.util.AbstractObjectPool;
019    import org.opengion.fukurou.util.ApplicationInfo;
020    import org.opengion.fukurou.util.Closer;
021    
022    import java.util.Map;
023    import java.util.HashMap;
024    import java.util.Locale;
025    import java.util.Properties;
026    import java.sql.Connection;
027    import java.sql.SQLException;
028    import java.sql.DriverManager;
029    import java.sql.DatabaseMetaData;
030    
031    /**
032     * ãƒ??タベã?スã®ã‚³ãƒã‚¯ã‚·ãƒ§ãƒ³ã‚ªãƒ–ジェクトをå–å¾—ã™ã‚‹ç‚ºã«ä½¿ç”¨ã™ã‚‹?Œãƒ•ァクトリクラスã§ã™ã?
033     *
034     * Connection.connection() メソãƒ?ƒ‰ã§?ŒConnectionオブジェクトをå–å¾—ã—ã¾ã™ã?
035     * Connection#close() メソãƒ?ƒ‰ã§?Œå?部çš?« ConnectionFactory ã«ã‚ªãƒ–ジェクトを戻ã?
036     * 事ã«ã‚ˆã£ã¦,Connectionオブジェクトã?プã?リングを行ãªã£ã¦ã?¾ã™ã?
037     *
038     * コãƒã‚¯ã‚·ãƒ§ãƒ³ã‚ªãƒ–ジェクトã??Œã?ールã‹ã‚‰è²¸ã—å?ã—ã¾ã™ã?
039     * ã¤ã¾ã‚Šï¼Œè²¸ã—å?ã—中ã«ã¯,プã?ルã«ã¯?Œã‚ªãƒ–ジェクトã?残ã£ã¦ã?¾ã›ã‚“ã€?
040     * ãã?状態ã§,コãƒã‚¯ã‚·ãƒ§ãƒ³ã‚ªãƒ–ジェクトをclose()ã—ãªã??åˆã?,オブジェクトãŒç ´æ£?•れã¦,
041     * 貸ã—å?ã—中カウントã¨å®Ÿéš›ã®ã‚ªãƒ–ジェクト数ãŒé£Ÿã„é•ã„,リソースãŒä¸è¶³ã—ã¾ã™ã?
042     * å¿?š,作æ?ã—ãŸã‚ªãƒ–ジェクトã?,close()メソãƒ?ƒ‰ã‚’呼ã³å‡ºã—ã¦,プã?ルã«è¿”ã—ã¦ä¸‹ã•ã??
043     *
044     * シスãƒ?ƒ ãƒªã‚½ãƒ¼ã‚¹ã® USE_DB_APPLICATION_INFO=true ã®å ´åˆã?コãƒã‚¯ã‚·ãƒ§ãƒ³ã«ã‚¢ãƒ—リケーション
045     * æƒ??を追記ã™ã‚‹ãŸã‚ã?ApplicationInfoオブジェクトを使用ã—ã¾ã™ã?
046     * ã“ã?オブジェクトã?ã€jsp/common/session-init.jsp ã«ã¦ãƒ¦ãƒ¼ã‚¶ãƒ¼æƒ??ã¨ã‚¢ãƒ—リケーション
047     * æƒ??ã‚’ç”»é¢ã‚¢ã‚¯ã‚»ã‚¹ã”ã¨ã«è¨­å®šã—ã¾ã™ã?
048     *
049     * @og.group ?¤?¢/Shell制御
050     * @og.rev 4.0.0.0 (2007/10/16) パッケージ移�hayabusa/db > fukurou/db)
051     *
052     * @version  4.0
053     * @author   Kazuhiko Hasegawa
054     * @since    JDK5.0,
055     */
056    public final class ConnectionFactory {
057            private static final Map<String,ConnectionPool> map = new HashMap<String,ConnectionPool>();
058    
059            // 4.0.0.0 (2007/10/10) キャãƒ?‚·ãƒ¥ã•れãŸã?åˆæœŸConnectionPool を使用
060            // 4.0.0.0 (2007/10/29) åˆæœŸå€¤ã‚’ã“ã“ã§ã‚»ãƒ?ƒˆã™ã‚‹
061            private static   String  DBID = "DEFAULT";
062            private static  ConnectionPool DEF_POOL ;
063    
064            // 4.0.0.0 (2007/10/17) シスãƒ?ƒ ä¾å­˜ã?改行記å·ã‚’ã‚»ãƒ?ƒˆã—ã¾ã™ã?
065            private static final String CR = System.getProperty( "line.separator" );
066    
067            // 4.0.0.0 (2007/10/25) hayabusaä¾å­˜ã‚’åˆ?‚‹ãŸã‚ã«è¿½åŠ?—ã¾ã?
068            private static final int BUFFER_MIDDLE = 200;
069    
070            private static DatabaseConfig  dbc;
071    
072            /**
073             *  ãƒ?ƒ•ォルトコンストラクターをprivateã«ã—ã¦ã€?
074             *  オブジェクトã?生æ?ã‚’ã•ã›ãªã?‚ˆã?«ã™ã‚‹ã€?
075             *
076             */
077            private ConnectionFactory() {
078            }
079    
080            /**
081             * åˆæœŸåŒ–メソãƒ?ƒ‰ã§ã™ã?<BR/>
082             *
083             * ??第二引数ã«XMLファイルをクラスローãƒ?Ÿºåº•ã‹ã‚‰ã?ç›¸å¯¾ãƒ‘ã‚¹ã§æŒ?®šã—ãŸå?åˆã?<BR/>
084             * ã€??ãã?XMLを利用ã—ã¦DBConfigオブジェクトを作æ?ã—ã¾ã™ã?例:ConnectionFactory.init( CONTEXT_NAME, "../DBConfig.xml")<BR/>
085             * ã€??nullã®å ´åˆã?WEB-INF/DBConfig.xmlを利用ã—ã¾ã™ã?例:ConnectionFactory.init( CONTEXT_NAME, null)<BR/>
086             * ??キャãƒ?‚·ãƒ¥åˆæœŸConnectionPoolã®ã‚­ãƒ¼ã‚’設定ã—ã¦ã‚­ãƒ£ãƒ?‚·ãƒ¥ãƒ—ã?ルを作りã¾ã™ã?<BR/>
087             * ã€??ã“ã?値ãŒnullã®å ´åˆã?"DEFAULT"ãŒè¨­å®šã•れã¾ã™ã?
088             * <BR/>
089             * <strong>ã“ã?クラスを利用ã™ã‚‹å ´åˆã?å¿?šæœ??ã«ã“ã?メソãƒ?ƒ‰ã‚’実行ã™ã‚‹å¿?¦ãŒã‚りã¾ã™ã?</strong><BR/>
090             * キャãƒ?‚·ãƒ¥ã¨DBConfigオブジェクトã?åŒæœŸåŒ–ã?ã•れã¦ã?ªã??ã§åˆæœŸåŒ–以外ã§ã®åˆ©ç”¨ã¯é¿ã‘ã¦ä¸‹ã•ã??<BR/>
091             *
092             * @og.rev 4.0.0.0 (2007/11/05) æ–°è¦ä½œæ?
093             *
094             * @param defPoolKey  åˆæœŸDBIDå?nullã®å ´åˆã?ã€?DEFAULT")
095             * @param XmlFileName DBConfig.xmlファイルã®ãƒ•ァイルå?nullã®å ´åˆã?ã€WEB-INF/DBConfig.xml)
096             */
097            public static void init( final String defPoolKey, final String XmlFileName ) {
098                    // DBConfigオブジェクトã?作æ?
099                    if( XmlFileName == null || XmlFileName.length() == 0 ) {
100                            dbc = new DatabaseConfig();
101                    }
102                    else {
103                            dbc = new DatabaseConfig( XmlFileName );
104                    }
105    
106                    if( defPoolKey == null || defPoolKey.length() == 0 || dbc.getDbid( defPoolKey ) == null ) {
107                            DBID = "DEFAULT";
108                    }
109                    else {
110                            DBID = defPoolKey;
111                    }
112                    EDbid edbid = dbc.getDbid( DBID );
113                    if( edbid == null ) {
114                            final String errMsg = "åˆæœŸåŒ–時ã«ã€æŒ‡å®šã?DBIDキーãŒå­˜åœ¨ã—ã¾ã›ã‚“ã€?
115                                    + "[Key ="
116                                    + DBID
117                                    + "]";
118                            throw new RuntimeException( errMsg );
119                    }
120    
121                    DEF_POOL = new ConnectionPool( edbid );
122            }
123    
124            /**
125             * コãƒã‚¯ã‚·ãƒ§ãƒ³ã‚ªãƒ–ジェクトをå–å¾—ã—ã¾ã™ã?
126             * é?„åˆæœŸåŒ–を行ãªã?º‹ã«ã‚ˆã‚Š,実際ã«å¿?¦ã¨ãªã‚‹ã¾ã§ã‚³ãƒã‚¯ã‚·ãƒ§ãƒ³ã‚ªãƒ–ジェクトã?
127             * 作æ?ã—ã¾ã›ã‚“ã€?
128             * æœ?¤§ãƒ—ã?ル数ã«é”ã—ã¦,ãªãŠã‹ã¤,ã™ã¹ã¦ã®ConnectionãŒè²¸ã—å?ã—中ã®å ´å?
129             *
130             * @og.rev 2.1.1.3 (2002/11/22) コãƒã‚¯ã‚·ãƒ§ãƒ³ID ã?null ã®å ´åˆã« DEFAULT ã‹ã‚‰æ‰?¾—ã™ã‚‹ã‚ˆã?«å¤‰æ›´ã€?
131             * @og.rev 3.1.0.0 (2003/03/20) Hashtable を使用ã—ã¦ã?‚‹ç®?‰€ã§ã€?žåŒæœŸã§ã‚‚æ§‹ã‚ãªã?®?‰€ã‚’ã?HashMap ã«ç½®æ›ãˆã€?
132             * @og.rev 3.5.6.2 (2004/07/05) æ–?­—å?ã®é€£çµã«StringBuilderを使用ã—ã¾ã™ã?
133             * @og.rev 3.8.7.0 (2006/12/15) アクセスログå–å¾—ã?為,ApplicationInfoオブジェクトを設å®?
134             * @og.rev 3.8.8.2 (2007/01/26) USE_DB_APPLICATION_INFO �pool.useApplicationInfo() 変更
135             * @og.rev 4.0.0.0 (2007/10/10) キャãƒ?‚·ãƒ¥ã•れãŸã?åˆæœŸConnectionPool を使用
136             * @og.rev 4.1.0.1 (2008/01/21) 登録時ã«ã€å¤§æ–?­—ã«å¤‰æ›ã™ã‚‹ã€?
137             *
138             * @param   dbid 接続å?ID
139             * @param   appInfo アプリ�?オブジェク�
140             *
141             * @return  コãƒã‚¯ã‚·ãƒ§ãƒ³ã‚ªãƒ–ジェクãƒ?
142             */
143            public static Connection connection( final String dbid , final ApplicationInfo appInfo ) {
144                    ConnectionPool pool ;
145                    if( dbid == null || dbid.length() == 0 || DBID.equalsIgnoreCase( dbid ) ) {
146                            pool = DEF_POOL ;
147                    }
148                    else {
149                            String udbid = dbid.toUpperCase( Locale.JAPAN );        // 大æ–?­—化
150                            synchronized( map ) {
151                                    pool = map.get( udbid );
152                                    // 接続IDãŒã?map ã«å­˜åœ¨ã—ãªã??å?
153                                    if( pool == null ) {
154                                            EDbid edbid = dbc.getDbid( udbid );
155                                            if( edbid == null ) {
156                                                    final String errMsg = "æŒ?®šã?DBIDキーãŒå­˜åœ¨ã—ã¾ã›ã‚“ã€?
157                                                            + "[Key ="
158                                                            + udbid
159                                                            + "]";
160                                                    throw new RuntimeException( errMsg );
161                                            }
162                                            pool = new ConnectionPool( edbid );
163                                            map.put( udbid,pool );
164                                    }
165                            }
166                    }
167    
168                    Connection conn = pool.newInstance();
169    
170                    // 3.8.7.0 (2006/12/15) アクセスログå–å¾—ã?為,ApplicationInfoオブジェクトを使用
171                    // 3.8.8.2 (2007/01/26) ORACLE 以外ã?ã€ä½¿ç”¨ã—ã¾ã›ã‚“ã€?
172                    // 4.0.0.0 (2007/11/29) 入れå­if ã®çµ±å?
173                    if( appInfo != null && pool.useApplicationInfo() ) {
174                            appInfo.callAppInfo( conn );
175                    }
176                    return conn;
177            }
178    
179            /**
180             * コãƒã‚¯ã‚·ãƒ§ãƒ³ã‚ªãƒ–ジェクトをプã?ãƒ«ã«æˆ»ã—ã¾ã™ã?
181             * Connectionオブジェクトã?,close()メソãƒ?ƒ‰ã§,自åˆ??身ã‚?ConnectionFactory ã®
182             * プã?ãƒ«ã«æˆ»ã—ã¾ã™ã?
183             * ãれ以外ã? コãƒã‚¯ã‚·ãƒ§ãƒ³ã‚ªãƒ–ジェクトをプã?ãƒ«ã«æˆ»ã™å?åˆã?,ã“ã?メソãƒ?ƒ‰ã‚’使用ã—ã¾ã™ã?
184             *
185             * @og.rev 2.1.1.3 (2002/11/22) コãƒã‚¯ã‚·ãƒ§ãƒ³ID ã?null ã®å ´åˆã« DEFAULT ã‹ã‚‰æ‰?¾—ã™ã‚‹ã‚ˆã?«å¤‰æ›´ã€?
186             * @og.rev 4.0.0.0 (2007/10/10) キャãƒ?‚·ãƒ¥ã•れãŸã?åˆæœŸConnectionPool を使用
187             * @og.rev 4.1.0.1 (2008/01/21) 登録時ã«ã€å¤§æ–?­—ã«å¤‰æ›ã™ã‚‹ã€?
188             *
189             * @param   conn コãƒã‚¯ã‚·ãƒ§ãƒ³ã‚ªãƒ–ジェクãƒ?
190             * @param   dbid 接続å?ID
191             */
192            public static void close( final Connection conn,final String dbid ) {
193                    if( conn != null ) {
194                            if( dbid == null || dbid.length() == 0 || DBID.equalsIgnoreCase( dbid ) ) {
195                                    DEF_POOL.release( conn ) ;
196                            }
197                            else {
198                                    String udbid = dbid.toUpperCase( Locale.JAPAN );        // 大æ–?­—化
199                                    synchronized( map ) {
200                                            ConnectionPool pool = map.get( udbid );
201                                            if( pool != null ) {
202                                                    pool.release( conn );
203                                            }
204                                    }
205                            }
206                    }
207            }
208    
209            /**
210             * コãƒã‚¯ã‚·ãƒ§ãƒ³ã‚ªãƒ–ジェクトを物ç?š„ã«å‰Šé™¤(クローズ)戻ã—ã¾ã™ã?
211             * ã“れã¯ã€ã‚³ãƒã‚¯ã‚·ãƒ§ãƒ³ç­‰ãŒã‚¨ãƒ©ãƒ¼ã‚’èµ·ã“ã—ãŸå?åˆã«ã€ã?ãƒ¼ãƒ«ã«æˆ»ã™ã?ã§ã¯ãªãã?
212             * 接続を閉ã˜ã‚‹å?åˆã«ã€ä½¿ç”¨ã•れã¾ã™ã?
213             *
214             * @og.rev 2.1.1.3 (2002/11/22) コãƒã‚¯ã‚·ãƒ§ãƒ³ID ã?null ã®å ´åˆã« DEFAULT ã‹ã‚‰æ‰?¾—ã™ã‚‹ã‚ˆã?«å¤‰æ›´ã€?
215             * @og.rev 4.0.0.0 (2007/10/10) キャãƒ?‚·ãƒ¥ã•れãŸã?åˆæœŸConnectionPool を使用
216             * @og.rev 4.1.0.1 (2008/01/21) 登録時ã«ã€å¤§æ–?­—ã«å¤‰æ›ã™ã‚‹ã€?
217             *
218             * @param   conn コãƒã‚¯ã‚·ãƒ§ãƒ³ã‚ªãƒ–ジェクãƒ?
219             * @param   dbid 接続å?ID
220             */
221            public static void remove( final Connection conn,final String dbid ) {
222                    if( conn != null ) {
223                            if( dbid == null || dbid.length() == 0 || DBID.equalsIgnoreCase( dbid ) ) {
224                                    DEF_POOL.remove( conn ) ;
225                            }
226                            else {
227                                    String udbid = dbid.toUpperCase( Locale.JAPAN );        // 大æ–?­—化
228                                    synchronized( map ) {
229                                            ConnectionPool pool = map.get( udbid );
230                                            if( pool != null ) {
231                                                    pool.remove( conn );
232                    //                              map.put( udbid,pool );
233                                            }
234                                    }
235                            }
236                    }
237            }
238    
239            /**
240             * コãƒã‚¯ã‚·ãƒ§ãƒ³ã‚ªãƒ–ジェクトを実際ã«ã™ã¹ã¦ã‚¯ãƒ­ãƒ¼ã‚ºã—ã¾ã™ã?
241             * コãƒã‚¯ã‚·ãƒ§ãƒ³ãƒ—ã?ルã®å†ç·¨æˆã‚„?Œç®¡ç??ã«ã‚ˆã‚‹å¼·åˆ¶ã‚¯ãƒ­ãƒ¼ã‚ºã«ä½¿ç”¨ã—ã¾ã™ã?
242             *
243             * クローズã«å¤±æ•?コãƒã‚¯ã‚·ãƒ§ãƒ³ãŒè²¸ã—å?ã—中)ã®å ´åˆã?,å†?ƒ¨çš?«
244             * DB_CLOSE_RETRY_TIME ã?‘å¾?©Ÿã—ã¦, DB_CLOSE_RETRY_COUNT 回数ã?‘,試行ã—ã¾ã™ã?
245             * ãれã§ã‚‚クローズã§ããªã??åˆã?, RuntimeException ã‚?throw ã—ã¾ã™ã?
246             *
247             * @og.rev 4.0.0.0 (2005/01/31) ロジãƒ?‚¯è¦‹ç›´ã—ã? pool.clear() ã§ã€åŸºæœ¬çš?«ã¯ã™ã¹ã¦å‰Šé™¤ã•れã¾ã™ã?
248             * @og.rev 4.0.0.0 (2007/10/10) キャãƒ?‚·ãƒ¥ã•れãŸã?åˆæœŸConnectionPool を使用
249             */
250            public static void realClose() {
251                    synchronized( DEF_POOL ) {
252                            if( ! DEF_POOL.isEmpty() ) {
253                                    DEF_POOL.clear();
254                            }
255                    }
256    
257                    final ConnectionPool[] pools ;
258                    synchronized( map ) {
259                            if( map.isEmpty() ) { return; }
260    
261                            pools = map.values().toArray( new ConnectionPool[map.size()] ) ;
262                            map.clear();
263                    }
264    
265                    ConnectionPool pool ;
266                    for( int i=0; i<pools.length ; i++ ) {
267                            pool = pools[i];
268                            if( pool != null && ! pool.isEmpty() ) {
269                                    pool.clear();
270                            }
271                    }
272            }
273    
274            /**
275             * ConnectionFactory ã®ç¾åœ¨ã®çжæ³?詳細メãƒ?‚»ãƒ¼ã‚¸)ã‚’è¿”ã—ã¾ã™ã?
276             * ã“れã¯?Œã‚³ãƒã‚¯ã‚·ãƒ§ãƒ³ãƒ—ã?ãƒ«ã®æ•°(æœ?¤§å€¤?Œä½œæ?æ¸ˆã¿æ•°ãªã©)を確èªã™ã‚‹ç‚ºã®ã‚‚ã?ã§ã™ã?
277             *
278             * @og.rev 4.0.0.0 (2007/10/10) キャãƒ?‚·ãƒ¥ã•れãŸã?åˆæœŸConnectionPool を使用
279             *
280             * @return  ç¾åœ¨ã®çŠ¶æ…‹è¡¨ç¤º
281             */
282            public static String information() {
283                    return information( true );
284            }
285    
286            /**
287             * ConnectionFactory ã®ç¾åœ¨ã®çжæ³ã‚’è¿”ã—ã¾ã™ã?
288             * ã“れã¯?Œã‚³ãƒã‚¯ã‚·ãƒ§ãƒ³ãƒ—ã?ãƒ«ã®æ•°(æœ?¤§å€¤?Œä½œæ?æ¸ˆã¿æ•°ãªã©)を確èªã™ã‚‹ç‚ºã®ã‚‚ã?ã§ã™ã?
289             * 引数ã«ã‚ˆã‚Šè©³ç´°ãƒ¡ãƒ?‚»ãƒ¼ã‚¸ã‹ã©ã?‹ã‚’指定ã§ãã¾ã™ã?
290             *
291             * @og.rev 4.0.0.0 (2007/10/10) キャãƒ?‚·ãƒ¥ã•れãŸã?åˆæœŸConnectionPool を使用
292             * @og.rev 5.3.4.0 (2011/04/01) 詳細メãƒ?‚»ãƒ¼ã‚¸ç”¨å¼•数を追åŠ?
293             *
294             * @param       isDetail        詳細メãƒ?‚»ãƒ¼ã‚¸ã‹ã©ã?‹ [true:詳細メãƒ?‚»ãƒ¼ã‚¸/false:簡易メãƒ?‚»ãƒ¼ã‚¸]
295             *
296             * @return  ç¾åœ¨ã®çŠ¶æ…‹è¡¨ç¤º
297             */
298            public static String information(final boolean isDetail ) {
299                    // 4.0.0.0 (2007/10/25) hybsã¨ã®ä¾å­˜é–¢ä¿‚ã‚’å¼±ã‚ã‚‹ãŸã‚ã€?
300                    final StringBuilder strBuf = new StringBuilder( BUFFER_MIDDLE );
301    
302                    strBuf.append( "Connection Information :" ).append( CR );
303    
304                    int rtnCnt = 0;
305                    synchronized( DEF_POOL ) {
306                            if( ! DEF_POOL.isEmpty() ) {
307                                    rtnCnt += DEF_POOL.size();
308                                    // 5.3.4.0 (2011/04/01) 詳細メãƒ?‚»ãƒ¼ã‚¸ç”¨å¼•数を追åŠ?
309                                    if( isDetail ) {
310                                            strBuf.append( DEF_POOL.toString() );
311                                            strBuf.append( "<br /><hr />" );
312                                    }
313                                    else {
314                                            strBuf.append( DEF_POOL.dbidInfo() );
315                                    }
316                            }
317                    }
318    
319                    ConnectionPool[] pools = null;
320                    synchronized( map ) {
321                            if( !map.isEmpty() ) {
322                                    pools = map.values().toArray( new ConnectionPool[map.size()] ) ;
323                            }
324                    }
325    
326                    if( pools != null ) {
327                            for( int i=0; i<pools.length ; i++ ) {
328                                    ConnectionPool pool = pools[i];
329                                    if( pool != null && ! pool.isEmpty() ) {
330                                            rtnCnt += pool.size();
331                                            // 5.3.4.0 (2011/04/01) 詳細メãƒ?‚»ãƒ¼ã‚¸ç”¨å¼•数を追åŠ?
332                                            if( isDetail ) {
333                                                    strBuf.append( pool.toString() );
334                                                    strBuf.append( "<br /><hr />" );
335                                            }
336                                            else {
337                                                    strBuf.append( pool.dbidInfo() );
338                                            }
339                                    }
340                            }
341                    }
342    
343                    strBuf.append( CR );
344    
345                    return strBuf.toString();
346            }
347    
348            /**
349             * ã“ã?接続ãŒã€PreparedStatement#getParameterMetaData() を使用ã™ã‚‹ã‹ã©ã?‹ã‚’判定ã—ã¾ã™ã?
350             *
351             * PreparedStatement ã«å¯¾ã—ã¦ã€String化ã•れ㟠数字ãªã©ã‚?setObject( int,String ) ã™ã‚‹ã¨ãã?
352             * ORACLE 㨠SQLServer ã¯ã€ãã®ã¾ã¾è¨­å®šã™ã‚Œã?ã€è?å‹•çš„ã«å¤‰æ›ã•れã¾ã™ã?
353             * postgreSQL ã§ã¯ã€ParameterMetaData#getParameterType(int) ã§ã€ã‚«ãƒ©ãƒ?‚¿ã‚¤ãƒ—ã‚’å–å¾—ã—ã€?
354             * setObject( int,String,int ) ã™ã‚‹å¿?¦ãŒã‚りã¾ã™ã?
355             * ãã?判定ã«ã€ã“ã®ãƒ¡ã‚½ãƒ?ƒ‰ã‚’使用ã—ã¾ã™ã?
356             * ã“ã?çµæžœã¯ã€ã‚ãã¾ã§ã€å„種ãƒ??タベã?ス毎ã?実地調査ã®çµæžœã‚’å?ã«ã€åˆ¤å®šçµæžœã‚?
357             * è¿”ã™ã‚ˆã†ã«ã—ã¦ã?¾ã™ã?
358             * ORACLE ã®å ´åˆã?ã€ä½¿ç”¨ã—ãªã?false)ãŒè¿”るよã†ã«è¨­å®šã—ã¦ã?¾ã™ã?
359             * SQLServer ã§ã¯ã€ORACLEã¨åŒæ§˜ã«ã€false ã‚’è¿”ã—ã¾ã™ã?
360             *
361             * ã“ã?メソãƒ?ƒ‰ã¯ã€å?ã€??ApplicationInfo#useParameterMetaData(Connection) ã«æœ‰ã£ãŸã‚‚ã®ã‚?
362             * EDbid ã‹ã‚‰å–å¾—ã™ã‚‹ã‚ˆã?«ä¿®æ­£ã—ãŸã‚‚ã?ã§ã™ã?
363             *
364             * @og.rev 5.3.8.0 (2011/08/01) æ–°è¦è¿½åŠ?
365             *
366             * @param dbid 接続å?ID
367             *
368             * @return      [true:使用ã™ã‚‹/false:ãã?ä»–]
369             */
370            public static boolean useParameterMetaData( final String dbid ) {
371                    final String udbid ;
372                    if( dbid == null || dbid.length() == 0 ) {
373                            udbid = DBID ;
374                    }
375                    else {
376                            udbid = dbid.toUpperCase( Locale.JAPAN );       // 大æ–?­—化
377                    }
378    
379                    EDbid edbid = dbc.getDbid( udbid );
380    
381                    return edbid.useParamMetaData();
382            }
383    
384            /**
385             * 接続å?ã®DBåã«å¯¾å¿œã—ãŸã?enum (DBName) ã‚’è¿”ã—ã¾ã?toUpperCase)ã€?
386             *
387             * @og.rev 5.1.4.0 (2010/03/01) getDBFullName ã®ä»£ã‚ã‚Šã«æ–°è¦ä½œæ?
388             *
389             * @param dbid 接続å?ID
390             *
391             * @return  接続å?ã®DBå?
392             */
393            public static String getDBName( final String dbid ) {
394                    final String dbName;
395    
396                    if( dbid == null || dbid.length() == 0 || DBID.equalsIgnoreCase( dbid ) ) {
397                            dbName = DEF_POOL.getDBName();
398                    }
399                    else {
400                            String udbid = dbid.toUpperCase( Locale.JAPAN );        // 大æ–?­—化
401                            ConnectionPool pool = null;
402                            synchronized( map ) {
403                                    pool = map.get( udbid );
404                                    if( pool == null ) {
405                                            close( connection( dbid, null ), dbid );
406                                    }
407                            }
408                            if( pool != null ) {
409                                    dbName = pool.getDBName();
410                            }
411                            else {
412                                    final String errMsg = "æŒ?®šã?DBIDキーã«å¯¾å¿œã™ã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ™ã?スåã‚’å–å¾—å?æ¥ã¾ã›ã‚“ã€?
413                                            + "[Key =" + dbid + "]";
414                                    throw new RuntimeException( errMsg );
415                            }
416                    }
417    
418                    return dbName.toUpperCase( Locale.JAPAN );
419            }
420    
421            /**
422             * 接続å?ã®DBåã‚’è¿”ã—ã¾ã™ã?
423             *
424             * @og.rev 4.3.7.0 (2009/06/01) æ–°è¦ä½œæ?
425             * @og.rev 5.1.4.0 (2010/03/01) å»?­¢
426             *
427             * @param dbid 接続å?ID
428             *
429             * @return  接続å?ã®DBå?ãƒã?ジョン
430             */
431    //      public static String getDBFullName( final String dbid ) {
432    //              String dbName = null;
433    //
434    //              if( dbid == null || dbid.length() == 0 || DBID.equalsIgnoreCase( dbid ) ) {
435    //                      dbName = DEF_POOL.getDBName() + " " + DEF_POOL.getDBVersion();
436    //              }
437    //              else {
438    //                      String udbid = dbid.toUpperCase( Locale.JAPAN );        // 大æ–?­—化
439    //                      ConnectionPool pool = null;
440    //                      synchronized( map ) {
441    //                              pool = map.get( udbid );
442    //                              if( pool == null ) {
443    //                                      close( connection( dbid, null ), dbid );
444    //                              }
445    //                      }
446    //                      if( pool != null ) {
447    //                              dbName = pool.getDBName() + " " + pool.getDBVersion();
448    //                      }
449    //              }
450    //              return dbName;
451    //      }
452    }
453    
454    /**
455     * ConnectionPool ã¯ã€AbstractObjectPool を継承ã—㟠オブジェクトã?ールã§ã™ã?
456     *
457     * コãƒã‚¯ã‚·ãƒ§ãƒ³ã‚ªãƒ–ジェクトをプã?ルã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šã€ConnectionFactory ã§
458     * 管ç?™ã‚?Map オブジェクトã?実æ?ã¨ã—ã¦ã€å„ID毎ã? コãƒã‚¯ã‚·ãƒ§ãƒ³ã‚’キープã—ã¾ã™ã?
459     *
460     * @og.group ?¤?¢/Shell制御
461     *
462     * @version  4.0
463     * @author   Kazuhiko Hasegawa
464     * @since    JDK5.0,
465     */
466    class ConnectionPool extends AbstractObjectPool<Connection> {
467            private final transient EDbid edbid;
468    
469            // 4.0.0.0 (2007/10/17) シスãƒ?ƒ ä¾å­˜ã?改行記å·ã‚’ã‚»ãƒ?ƒˆã—ã¾ã™ã?
470            private static final String CR = System.getProperty( "line.separator" );
471    
472            /**
473             *  DBID を指定ã—ã¦ä½œæ?ã™ã‚‹ コンストラクター
474             *  DBID をキーã«?¤ HybsSystem.sys メソãƒ?ƒ‰ã®ãƒ??タベã?ス変数をå–å¾—ã—ã¾ã™ã?
475             *  å–å¾—ã™ã‚‹ã?ã¯?¤ DBID + _DB_URL?_DB_USER?_DB_PASSWD?_DB_MINCOUNT?_DB_MAXCOUNT
476             *  ã§ã™ã?
477             *  DBID ã?null ã®å ´åˆã???DEFAULT" ãŒä½¿ç”¨ã•れã¾ã™ã?
478             *
479             * @og.rev 3.5.4.3 (2004/01/05) キャãƒ?‚·ãƒ¥ã®å¯¿å‘½ã‚’指å®?
480             * @og.rev 3.5.4.7 (2004/02/06) DBID ã®ã‚¼ãƒ­ã‚¹ãƒˆãƒªãƒ³ã‚°ãƒã‚§ãƒ?‚¯è¿½åŠ?
481             * @og.rev 4.0.0.0 (2007/10/10) キャãƒ?‚·ãƒ¥ã•れãŸã?åˆæœŸConnectionPool を使用
482             * @og.rev 4.0.0.0 (2007/10/25) DB設定情報ã®XML化ã«ä¼´ã?¤‰æ›´
483             *
484             * @param   edbid 接続å?æƒ??オブジェクãƒ?
485             */
486            public ConnectionPool( final EDbid edbid ) {
487                    // 4.0.0.0 XML化ã«ä¼´ã?ƒ­ãƒ¼ãƒ‰å?を変更
488                    this.edbid      =       edbid;
489                    init( edbid.getMincount(),edbid.getMaxcount(),true,edbid.getPooltime() );
490            }
491    
492            /**
493             * オブジェクトã?ールã‹ã‚‰å‰Šé™¤ã™ã‚‹ã¨ãã«å‘¼ã°ã‚Œã¾ã™ã?
494             * ã“ã?メソãƒ?ƒ‰ã§å?‚ªãƒ–ジェクトã”ã¨ã®çµ‚äº??ç?‚’行ã„ã¾ã™ã?
495             * 例ãˆã°?¤ãƒ??タベã?スコãƒã‚¯ã‚·ãƒ§ãƒ³ã§ã‚れã°?¤close() 処ç?ªã©ã§ã™ã?
496             *
497             * @og.rev 3.5.4.8 (2004/02/23) SQLException ã¯ç„¡è¦–ã—ã¾ã™ã?
498             * @og.rev 3.5.6.0 (2004/06/18) synchronized を解除ã—ã¾ã™ã?
499             *
500             * @param  obj 終äº??ç?‚’行ã†ã‚ªãƒ–ジェクãƒ?
501             */
502            protected void objectFinal( final Connection obj ) {
503                    Closer.connClose( obj );
504            }
505    
506            /**
507             * コãƒã‚¯ã‚·ãƒ§ãƒ³ã‚ªãƒ–ジェクトを作æ?ã—ã¾ã™ã?
508             * DriverManager.getConnection ã«ã‚ˆã‚Šä½œæ?ã•れãŸConnection ã‚?Connection ã§
509             * ラãƒ?ƒ”ングã—ã¾ã™ã?
510             * Connectionオブジェクトã?,close()メソãƒ?ƒ‰ã§,自åˆ??身ã‚?ConnectionFactory ã®
511             * プã?ãƒ«ã«æˆ»ã—ã¾ã™ã?
512             *
513             * @og.rev 3.3.3.3 (2003/08/06) コãƒã‚¯ã‚·ãƒ§ãƒ³ã«å¯¾ã—ã¦ã€setTransactionIsolation ã‚’ã?設定ã—ã¦ãŠãã€?
514             * @og.rev 3.5.2.0 (2003/10/20) 接続情報ã«ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ã?スåã?ドライãƒåæƒ??を追åŠ?™ã‚‹ã?
515             * @og.rev 3.5.6.0 (2004/06/18) synchronized を解除ã—ã¾ã™ã?
516             * @og.rev 3.8.8.2 (2007/01/26) useAppInfo を設定ã—ã¾ã™ã?
517             * @og.rev 4.0.0.0 (2007/10/30) ä¿æŒæƒ??オブジェクト化ã«ä¼´ã?¤‰æ›´
518             * @og.rev 5.1.2.0 (2010/01/01) MySQL対å¿?明示çš?«ã€TRANSACTION_READ_COMMITTED を指定ã™ã‚‹ã?
519             * @og.rev 5.5.2.0 (2012/05/01) properties対�
520             *
521             * @return  コãƒã‚¯ã‚·ãƒ§ãƒ³ã‚ªãƒ–ジェクãƒ?
522             */
523            protected Connection createInstance() {
524                    Connection conn = null;
525                    try {
526            //              DriverManager.setLogWriter( HybsSystem.out );                   // ドライãƒã?ã®ãƒ­ã‚°
527    
528                            // 5.5.2.0 (2012/05/01) propertyã®è¿½åŠ??ç?¨ã€æŽ¥ç¶šã?propertiesåŒ?
529                            Properties prop = new Properties (edbid.getProps());
530                            prop.put ( "user", edbid.getUser() );
531                            prop.put ( "password", edbid.getPassword() );
532    
533    //                      conn = DriverManager.getConnection( edbid.getUrl(), edbid.getUser(), edbid.getPassword() );
534                            conn = DriverManager.getConnection( edbid.getUrl(), prop );
535            //              conn.setReadOnly( true );
536                            conn.setReadOnly( edbid.isReadonly() );
537    
538                            conn.setAutoCommit( false );
539                            conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);  // åˆæœŸå€¤
540            //              ((OracleConnection)conn).setDefaultExecuteBatch(1);  // åˆæœŸå€¤
541            //              ((OracleConnection)conn).setDefaultRowPrefetch(20);  // åˆæœŸå€¤
542    
543                            // 3.5.2.0 (2003/10/20) 接続情報ã«ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ã?スåã?ドライãƒåæƒ??を追åŠ?™ã‚‹ã?
544                            // 4.0.0.0 (2007/10/26) 登録先をオブジェクト化
545                            if( edbid.getDbProductName() == null ) {
546                                    DatabaseMetaData meta = conn.getMetaData();
547                                    edbid.setMetaDataInfo( meta );
548                            }
549                            return conn ;
550                    }
551                    catch ( SQLException ex ) {
552                            String errMsg = "コãƒã‚¯ãƒˆã™ã‚‹ã“ã¨ãŒå?æ¥ã¾ã›ã‚“ã€? + CR
553                                                    + "DBID=[" + edbid.getDbidKey() + "]" + CR
554                                                    + ex.getMessage() + " , status=" + ex.getSQLState();
555                            Closer.connClose( conn );
556                            throw new RuntimeException( errMsg,ex );                // 3.5.5.4 (2004/04/15) 引数ã®ä¸¦ã³é ?¤‰æ›´
557                    }
558            }
559    
560            /**
561             * アクセスログå–å¾—ã?為ã®DBMS_APPLICATION_INFOã®ä½¿ç”¨å¯å¦ã‚’å–å¾—ã—ã¾ã?åˆæœŸå€¤:true)ã€?
562             *
563             * ãƒ??タベã?スã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãƒ­ã‚°å–å¾—ã?為ã€ã‚¨ãƒ³ã‚¸ãƒ³ã§æŽ¥ç¶šã™ã‚‹ã‚³ãƒã‚¯ã‚·ãƒ§ãƒ³ã«ã¤ã?¦
564             * DBMS_APPLICATION_INFO.SET_CLIENT_INFO 㨠SET_MODULE を呼ã³å‡ºã—ã¦ã?¾ã™ã?
565             * ã“ã?処ç??ã€ORACLEã¨ã®æŽ¥ç¶šã?ã¿æœ‰åйã§ã™ã?ã§ã€æŽ¥ç¶šå?ãƒ??タベã?スã?ORACLE 以外ã?
566             * false ã‚’è¿”ã—ã¾ã™ã?
567             * ORACLE ã®å ´åˆã?ã€ã‚·ã‚¹ãƒ?ƒ ãƒªã‚½ãƒ¼ã‚¹ã® USE_DB_APPLICATION_INFO 属æ?ã®è¨­å®šå?ã‚?
568             * è¿”ã—ã¾ã™ã?
569             * ã“ã?設定å?ã®åˆæœŸå€¤ã¯ã€true ã§ã™ã?
570             *
571             * @og.rev 3.8.8.2 (2007/01/26) æ–°è¦è¿½åŠ?
572             *
573             * @return  true:使用ã™ã‚‹/false:使用ã—ãªã?
574             */
575            public boolean useApplicationInfo() { return edbid.isApplicationInfo(); }
576    
577            /**
578             * 接続å?ã®DBåã‚’è¿”ã—ã¾ã™ã?
579             *
580             * @og.rev 4.3.7.0 (2009/06/01) æ–°è¦ä½œæ?
581             *
582             * @return  接続å?ã®DBå?
583             */
584            public String getDBName() {
585                    return edbid.getDbProductName();
586            }
587    
588            /**
589             * 接続å?ã®DBãƒã?ジョンを返ã—ã¾ã™ã?
590             *
591             * @og.rev 4.3.7.0 (2009/06/01) æ–°è¦ä½œæ?
592             *
593             * @return 接続å?ã®DBãƒã?ジョン
594             */
595            public String getDBVersion() {
596                    return edbid.getDbProductVersion();
597            }
598    
599            /**
600             * 接続å?ã®ç°¡æ˜“ãªå†?ƒ¨æƒ??ã‚’è¿”ã—ã¾ã™ã?
601             *
602             * @og.rev 5.3.4.0 (2011/04/01) toString() ã®ç°¡æ˜“版
603             *
604             * @return 接続å?ã®ç°¡æ˜“ãªå†?ƒ¨æƒ??
605             */
606            public String dbidInfo() {
607                    return edbid.info();
608            }
609    
610            /**
611             * å†?ƒ¨çжæ³ã‚’簡易的ã«è¡¨ç¾ã—ãŸæ–?­—å?ã‚’è¿”ã—ã¾ã™ã?
612             * DBID?URL?USER?ã?ールサイズ ã‚’è¿”ã—ã¾ã™ã?
613             *
614             * @og.rev 3.5.2.0 (2003/10/20) 接続情報ã«ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ã?スåã?ドライãƒåæƒ??を追åŠ?™ã‚‹ã?
615             * @og.rev 3.5.6.6 (2004/08/23) åŒæœŸåŒ–方法を統ä¸?™ã‚‹ç‚ºã€synchronized ã‚’ã¤ã‘ã¾ã™ã?(別é€?è¦æ¤œè¨?
616             * @og.rev 4.0.0.0 (2007/10/29) EDbidã®toStringを呼ã¶ã‚ˆã†ã«å¤‰æ›´
617             *
618             * @return   ã“ã?オブジェクトã?ãƒ¼ãƒ«ã®æ–?­—å?表ç¾
619             */
620            public String toString() {
621                    StringBuilder buf = new StringBuilder();
622                    buf.append( edbid.toString() );
623                    buf.append( super.toString() );
624                    return buf.toString();
625            }
626    }