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.hayabusa.db;
017
018import java.util.Map;                                                                           // 8.5.6.1 (2024/03/29)
019
020import java.sql.Connection;
021import java.sql.ResultSet;
022import java.sql.SQLException;
023import java.sql.Array;                                                                          // 8.5.6.1 (2024/03/29)
024import java.sql.CallableStatement;                                                      // 8.5.6.1 (2024/03/29)
025
026import org.opengion.fukurou.system.HybsConst ;                          // 6.1.0.0 (2014/12/26)
027import org.opengion.fukurou.system.ThrowUtil;                           // 6.4.2.0 (2016/01/29)
028import org.opengion.fukurou.util.ErrorMessage;
029import org.opengion.hayabusa.common.HybsSystem;
030import org.opengion.hayabusa.common.HybsSystemException;
031import org.opengion.hayabusa.resource.ResourceManager;
032
033/**
034 * Query インターフェースを継承した Query の実装クラスです。
035 * クエリークラスにステートメントを与えて execute()することにより内部に DBTableModel を
036 * 作成します。
037 * このクラスは、Abstract クラスのため、実装は個々のサブクラスで行います。
038 * 唯一実装する必要があるのは、execute() メソッドだけです。
039 *
040 * @og.group DB検索
041 * @og.group DB登録
042 *
043 * @version  4.0
044 * @author       Kazuhiko Hasegawa
045 * @since    JDK5.0,
046 */
047public class AbstractQuery implements Query {
048        /** システムの改行コードを設定します。*/
049        protected static final String CR                 = HybsConst.CR;                        // 6.1.0.0 (2014/12/26) refactoring
050        /** StringBilderなどの初期値を設定します。   {@value} */
051        protected static final int BUFFER_MIDDLE = HybsConst.BUFFER_MIDDLE;     // 6.1.0.0 (2014/12/26) refactoring
052
053        private Connection              connection      ;
054        private int                     rtnCode         = ErrorMessage.OK;
055        private ErrorMessage    errMessage      ;
056        private ResourceManager resource        ;
057
058        private DBTableModel table                      ;
059        private String           stmtString             ;
060        private int              executeCount   = -1 ;
061        private int              skipRowCount   ;
062        private int              maxRowCount    = HybsSystem.sysInt( "DB_MAX_ROW_COUNT" ) ;
063        private boolean          updateFlag             = true ;
064        private DBEditConfig config                     ;               // 5.3.6.0 (2011/06/01)
065
066        // 5.1.9.0 (2010/08/01) DB_RETRY_COUNT,DB_RETRY_TIME 廃止
067        /** データ検索時の最大処理制限時間 */
068        protected static final int DB_MAX_QUERY_TIMEOUT = HybsSystem.sysInt( "DB_MAX_QUERY_TIMEOUT" ) ;
069
070        /** 6.9.3.0 (2018/03/26) データ検索時のフェッチサイズ {@value} */
071        protected static final int DB_FETCH_SIZE                = HybsConst.DB_FETCH_SIZE;      // 6.9.4.1 (2018/04/09)
072
073//      /** データ検索時のフェッチサイズを設定します。 */
074//      protected static final int DB_FETCH_SIZE  = HybsConst.DB_FETCH_SIZE;    // 6.9.4.1 (2018/04/09)
075
076        // 3.5.2.0 (2003/10/20) 内部オブジェクトタイプ名を システムパラメータ で定義します。
077        /** 内部オブジェクトタイプ名  {@value} */
078        public static final String ARG_ARRAY            = "ARG_ARRAY" ;
079        /** 内部オブジェクトタイプ名  {@value} */
080        public static final String SYSARG_ARRAY         = "SYSARG_ARRAY" ;
081        /** 内部オブジェクトタイプ名  {@value} */
082        public static final String ERR_MSG                      = "ERR_MSG" ;
083        /** 内部オブジェクトタイプ名  {@value} */
084        public static final String ERR_MSG_ARRAY        = "ERR_MSG_ARRAY" ;
085
086        private String  updQuery                ;                       // 7.2.9.1 (2020/10/23)
087        private String  insQuery                ;                       // 7.2.9.1 (2020/10/23)
088        private String  selQuery                ;                       // 7.4.1.0 (2021/04/23)
089
090        /**
091         * デフォルトコンストラクター
092         *
093         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
094         */
095        protected AbstractQuery() { super(); }          // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
096
097        /**
098         * Connectionオブジェクトを外部から設定します。
099         *
100         * 通常は、Transaction と 接続先(DBID) を使用して作成した Connection を渡します。
101         * このクラスでは、Connection の close() や、ConnectionFactory への返却なども
102         * 行いません。それらは、外部処理(通常は、Transactionオブジェクト)で行います。
103         *
104         * Connection には、null は登録できません。
105         *
106         * @og.rev 6.3.6.1 (2015/08/28) 新規追加
107         *
108         * @param       conn    Connectionオブジェクト
109         */
110        @Override       // Query
111        public void setConnection( final Connection conn ) {
112                if( conn == null ) {
113                        final String errMsg = "Connection に null は指定できません。" + CR ;
114                        throw new HybsSystemException( errMsg );
115                }
116                connection = conn;
117        }
118
119        /**
120         * ステートメント文字列をセットします。
121         *
122         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
123         *
124         * @param       stmt ステートメント文字列
125         *
126         */
127        @Override       // Query
128        public void setStatement( final String stmt ) {
129                this.stmtString = stmt.trim();
130        }
131
132        /**
133         * ステートメント文字列を取り出します。
134         *
135         * @return       ステートメント文字列
136         *
137         */
138        @Override       // Query
139        public String getStatement() {
140                return stmtString;
141        }
142
143        /**
144         * ステートメント文字列(UPDATE,INSERT)をセットします。
145         *
146         * @og.rev 7.2.9.1 (2020/10/23) TableUpdateParamTag のマージ(UPDATE,INSERT)対応
147         * @og.rev 7.4.1.0 (2021/04/23) sqlType="MERGE" 時のみ有効で、where 条件で存在すれば何もしない
148         *
149         * @param   update UPDATEステートメント文字列
150         * @param   insert INSERTステートメント文字列
151         * @param   select SELECTステートメント文字列(あれば何もしない、なければINSERT処理の判定用)
152         */
153//      public void setMergeStatement( final String update , final String insert ) {
154        @Override       // Query
155        public void setMergeStatement( final String update , final String insert , final String select ) {
156                updQuery = update;
157                insQuery = insert;
158                selQuery = select;
159        }
160
161        /**
162         * ステートメント文字列(UPDATE,INSERT,SELECT)を取り出します。
163         *
164         * @og.rev 7.2.9.1 (2020/10/23) TableUpdateParamTag のマージ(UPDATE,INSERT)対応
165         * @og.rev 7.2.9.3 (2020/11/06) 早い段階でエラーにしておきます。
166         * @og.rev 7.4.1.0 (2021/04/23) sqlType="MERGE" 時のみ有効で、where 条件で存在すれば何もしない
167         *
168         * @return  ステートメント文字列の配列(UPDATE,INSERTの順番)
169         */
170        @Override       // Query
171        public String[] getMergeStatement() {
172        //      if( updQuery == null || insQuery == null ) {
173        //              final String errMsg = "Merge処理を行うには、INSERTとUPDATEの両方のQUERYが必要です。" + CR
174        //                      + " updQuery=" + updQuery + CR
175        //                      + " insQuery=" + insQuery + CR
176        //                      + " query   =" + stmtString ;
177        //
178        //              throw new UnsupportedOperationException( errMsg );
179        //      }
180
181//              return new String[] { updQuery,insQuery } ;
182                return new String[] { updQuery,insQuery,selQuery } ;
183        }
184
185        /**
186         * 引数配列付のクエリーを実行します。
187         * 処理自体は、#execute() と同様に、各サブクラスの実装に依存します。
188         * これは、PreparedQuery で使用する引数を配列でセットするものです。
189         * select * from emp where deptno = ? and job = ? などの PreparedQuery や
190         * { call xxxx( ?,?,? ) } などの CallableStatement の ? 部分の引数を
191         * 順番にセットしていきます。
192         * ※ このクラスでは実装されていません。
193         *
194         * @og.rev 6.1.1.0 (2015/01/17) 引数配列を可変引数にして、execute() を含めて定義します。
195         *
196         * @param       args オブジェクトの引数配列(可変長引数)
197         */
198        @Override       // Query
199        public void execute( final String... args ) {                   // 6.1.1.0 (2015/01/17) refactoring
200                final String errMsg = "このクラスでは実装されていません。execute( String... )";
201                throw new UnsupportedOperationException( errMsg );
202        }
203
204        /**
205         * 引数配列付のクエリーを実行します。
206         * 処理自体は、#execute() と同様に、各サブクラスの実装に依存します。
207         * これは、PreparedQuery で使用する引数を配列でセットするものです。
208         * select * from emp where deptno = ? and job = ? などの PreparedQuery の
209         * ? 部分の引数を
210         * 順番にセットしていきます。
211         * ※ このクラスでは実装されていません。
212         *
213         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
214         *
215         * @param   keys オブジェクトのキー配列
216         * @param   args オブジェクトの引数配列(可変長引数)
217         */
218        @Override       // Query
219        public void execute( final String[] keys, final String... args ) {                      // 6.1.1.0 (2015/01/17) refactoring
220                final String errMsg = "このクラスでは実装されていません。execute( String[],String... )";
221                throw new UnsupportedOperationException( errMsg );
222        }
223
224        /**
225         * 引数配列付のクエリーを実行します。
226         * 処理自体は、#execute() と同様に、各サブクラスの実装に依存します。
227         * これは、PreparedQuery で使用する引数を配列でセットするものです。
228         * select * from emp where deptno = ? and job = ? などの PreparedQuery の
229         * ? 部分の引数を
230         * 順番にセットしていきます。
231         * ※ このクラスでは実装されていません。
232         *
233         * @og.rev 4.0.0.0 (2005/01/31) 引数をすべて受け取って実行するメソッドを標準メソッドとして追加
234         *
235         * @param       names           カラム名(CSV形式)
236         * @param       dbArrayType     アレイタイプ名称
237         * @param       sysArg          DBSysArg配列
238         * @param       userArg         DBUserArg配列
239         */
240        @Override       // Query
241        public void execute( final String names,final String dbArrayType,
242                                                final DBSysArg[] sysArg,final DBUserArg[] userArg ) {
243                final String errMsg = "このクラスでは実装されていません。execute( String,String,DBSysArg[],DBUserArg[] )";
244                throw new UnsupportedOperationException( errMsg );
245        }
246
247        /**
248         * 引数配列付のクエリーを実行します。
249         * 処理自体は、#execute() と同様に、各サブクラスの実装に依存します。
250         * これは、PreparedQuery で使用する引数を配列でセットするものです。
251         * select * from emp where deptno = ? and job = ? などの PreparedQuery の
252         * [カラム名] 部分の引数を、DBTableModelから順番にセットしていきます。
253         * ※ このクラスでは実装されていません。
254         *
255         * @param   rowNo 選択された行番号配列(登録する対象行)
256         * @param   table DBTableModelオブジェクト(登録する元データ)
257         */
258        @Override       // Query
259        public void execute( final int[] rowNo, final DBTableModel table ) {
260                final String errMsg = "このクラスでは実装されていません。execute( final int[] rowNo, final DBTableModel table )";
261                throw new UnsupportedOperationException( errMsg );
262        }
263
264        /**
265         * Oracle関係のPL/SQLなどを処理する 共通メソッド
266         *
267         * これは、execute 処理の中でも、Oracle系 CallableStatement の共通処理部分です。
268         * 引数の ExceptionBiConsumer で、各サブクラスの個別のパラメータ設定処理を行います。
269         *
270         * @og.rev 8.5.6.1 (2024/03/29) Oracle関係のPL/SQLなどを処理する
271         *
272         * @param   biConsumer CallableStatementとConnectionを受け取って結果を返さない関数型インタフェース
273         * @param   clsName エラーメッセージ生成時のサブクラス名
274         */
275        protected void execute( final ExceptionBiConsumer<CallableStatement,Connection> biConsumer, final String clsName ) {
276                final Connection conn = getConnection();
277                // 6.4.2.1 (2016/02/05) try-with-resources 文
278                try( CallableStatement callStmt = conn.prepareCall( getStatement() ) ) {
279                        callStmt.setQueryTimeout( DB_MAX_QUERY_TIMEOUT );
280                        callStmt.setFetchSize( DB_FETCH_SIZE );                 // 6.9.3.0 (2018/03/26)
281
282                        final Map<String,Class<?>> map = conn.getTypeMap();
283                        map.put( ERR_MSG,DBErrMsg.class );                              // 4.0.0 (2005/01/31)
284                        conn.setTypeMap(map);                                                   // 8.5.6.1 (2024/03/29) JavaDoc参照。getTypeMap() のMap変更後、setTypeMap(Map)が必要。
285
286                        biConsumer.accept( callStmt,conn );
287
288                        callStmt.execute();
289
290                        final int rtnCode = callStmt.getInt(1);
291                        setErrorCode( rtnCode );
292                        if( rtnCode > ErrorMessage.OK ) {               // 正常以外の場合
293                                final ErrorMessage errMessage = new ErrorMessage( clsName + " Error!!" );
294                                final Array rtn3 = callStmt.getArray(2);                                                // 6.0.0.0 (2014/04/11) Oracle11g(11.2.0.3のドライバ)対応
295                                // 8.5.4.2 (2024/01/12) PMD 7.0.0 ForLoopCanBeForeach
296//                              final Object[] rtnval3 = (Object[])rtn3.getArray();
297//                              for( int i=0; i<rtnval3.length; i++ ) {
298//                                      final DBErrMsg er = (DBErrMsg)rtnval3[i];
299                                for( final Object rtnval : (Object[])rtn3.getArray() ) {
300                                        final DBErrMsg er = (DBErrMsg)rtnval;
301                                        if( er == null ) { break; }
302                                        errMessage.addMessage( er.getErrMsg() );
303                                }
304                                setErrorMessage( errMessage );
305                        }
306                }
307                catch( final SQLException ex) {         // catch は、close() されてから呼ばれます。
308                        setErrorCode( ErrorMessage.EXCEPTION );
309                        final String errMsg = ex.getMessage() + ":" + ex.getSQLState() + CR
310                                                + getStatement() + CR;
311                        throw new HybsSystemException( errMsg,ex );             // 3.5.5.4 (2004/04/15) 引数の並び順変更
312                }
313        }
314
315        /**
316         * クエリーの実行結果件数をセットします。
317         * 初期値は -1 です。(クエリーが失敗した場合や、CallableStatement の呼び出し等で
318         * 実行件数が明確でない場合の戻り値)。
319         *
320         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
321         *
322         * @param       executeCount 実行結果件数
323         */
324        protected void setExecuteCount( final int executeCount ) {
325                this.executeCount = executeCount;
326        }
327
328        /**
329         * クエリーの実行結果を返します。
330         * クエリーが失敗した場合や、CallableStatement の呼び出し等で実行件数が明確でない
331         * 場合は、-1 が返されます。
332         *
333         * @return      実行結果件数
334         */
335        @Override       // Query
336        public int getExecuteCount() {
337                return executeCount;
338        }
339
340        /**
341         * DBTableModel をセットします。
342         * なお、検索系実行前に setDBTableModel() でテーブルをセットしていたとしても
343         * そのオブジェクトは破棄されて、新しい DBTableModel が生成されます。
344         *
345         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
346         *
347         * @param       table DBTableModelオブジェクト
348         */
349        protected void setDBTableModel( final DBTableModel table ) {
350                this.table = table;
351        }
352
353        /**
354         * 実行結果の DBTableModel を返します。
355         *
356         * @return      DBTableModelオブジェクト
357         */
358        @Override       // Query
359        public DBTableModel getDBTableModel() {
360                return table;
361        }
362
363        /**
364         * データベースの最大検索件数を返します。
365         *              (初期値:DB_MAX_ROW_COUNT[={@og.value SystemData#DB_MAX_ROW_COUNT}])。
366         * データベース自体の検索は、指定されたSQLの全件を検索しますが、
367         * DBTableModelのデータとして登録する最大件数をこの値に設定します。0は無制限です。
368         * サーバーのメモリ資源と応答時間の確保の為です。
369         *
370         * @return      最大検索件数
371         */
372        @Override       // Query
373        public int getMaxRowCount() {
374                return maxRowCount;
375        }
376
377        /**
378         * データベースの最大検索件数をセットします。
379         * データベース自体の検索は、指定されたSQLの全件を検索しますが、
380         * DBTableModelのデータとして登録する最大件数をこの値に設定します。
381         * サーバーのメモリ資源と応答時間の確保の為です。
382         * ゼロ、または、負の値を設定すると、無制限(Integer.MAX_VALUE)になります。
383         *
384         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
385         * @og.rev 4.0.0.0 (2005/08/31) ゼロ、または、負の値は、無制限(Integer.MAX_VALUE)にする。
386         *
387         * @param       maxRowCount 最大検索件数
388         */
389        @Override       // Query
390        public void setMaxRowCount( final int maxRowCount ) {
391                this.maxRowCount = maxRowCount > 0 ? maxRowCount : Integer.MAX_VALUE ;
392        }
393
394        /**
395         * データベースの検索スキップ件数を返します。
396         * データベース自体の検索は、指定されたSQLの全件を検索しますが、
397         * DBTableModelのデータとしては、スキップ件数分は登録されません。
398         * サーバーのメモリ資源と応答時間の確保の為です。
399         *
400         * @return      最大検索件数
401         */
402        @Override       // Query
403        public int getSkipRowCount() {
404                return skipRowCount;
405        }
406
407        /**
408         * データベースの検索スキップ件数をセットします。
409         * データベース自体の検索は、指定されたSQLの全件を検索しますが、
410         * DBTableModelのデータとしては、スキップ件数分は登録されません。
411         * サーバーのメモリ資源と応答時間の確保の為です。
412         *
413         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
414         *
415         * @param       skipRowCount スキップ件数
416         */
417        @Override       // Query
418        public void setSkipRowCount( final int skipRowCount ) {
419                this.skipRowCount = skipRowCount;
420        }
421
422        /**
423         * アップデートフラグをセットします。
424         * これは、Query で更新処理の SQL 文を実行したときにセットされます。
425         * 更新処理が実行:true / 検索処理のみ:false をセットします。
426         * このメソッドを呼び出さない場合は、デフォルト:true  です。
427         *
428         * @og.rev 2.1.2.3 (2002/12/02) データベース更新時に、更新フラグをセットするように変更
429         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
430         *
431         * @param       up      アップデートされたかどうか[true:更新処理/false:検索処理]
432         */
433        protected void setUpdateFlag( final boolean up ) {
434                updateFlag = up;
435        }
436
437        /**
438         * アップデートフラグを取得します。
439         * これは、Query で更新処理の SQL 文を実行したときに true にセットされます。
440         * 更新処理が実行:true / 検索処理のみ:false を取得できます。
441         *
442         * @og.rev 2.1.2.3 (2002/12/02) データベース更新時に、更新フラグをセットするように変更
443         * @og.rev 4.0.0.0 (2007/07/20) メソッド名変更( getUpdateFlag() ⇒ isUpdate() )
444         *
445         * @return       アップデートされたかどうか[true:更新処理/false:検索処理]
446         */
447        @Override       // Query
448        public boolean isUpdate() {
449                return updateFlag ;
450        }
451
452        /**
453         * リソースマネージャーをセットします。
454         * これは、言語(ロケール)に応じた DBColumn をあらかじめ設定しておく為に
455         * 必要です。
456         * リソースマネージャーが設定されていない、または、所定のキーの DBColumn が
457         * リソースに存在しない場合は、内部で DBColumn オブジェクトを作成します。
458         *
459         * @og.rev 4.0.0.0 (2005/01/31) lang ⇒ ResourceManager へ変更
460         *
461         * @param       resource リソースマネージャー
462         */
463        @Override       // Query
464        public void setResourceManager( final ResourceManager resource ) {
465                this.resource = resource;
466        }
467
468        /**
469         * エラーコード を取得します。
470         * エラーコード は、ErrorMessage クラスで規定されているコードです。
471         *
472         * @return   エラーコード
473         */
474        @Override       // Query
475        public int getErrorCode() {
476                return rtnCode;
477        }
478
479        /**
480         * エラーコード をセットします。
481         * エラーコード は、ErrorMessage クラスで規定されているコードです。
482         *
483         * @param   cd エラーコード
484         */
485        protected void setErrorCode( final int cd ) {
486                rtnCode = cd;
487        }
488
489        /**
490         * エラーメッセージオブジェクト を取得します。
491         *
492         * @return   エラーメッセージオブジェクト
493         */
494        @Override       // Query
495        public ErrorMessage getErrorMessage() {
496                return errMessage;
497        }
498
499        /**
500         * エラーメッセージオブジェクト をセットします。
501         *
502         * @param   em エラーメッセージオブジェクト
503         */
504        protected void setErrorMessage( final ErrorMessage em ) {
505                errMessage = em;
506        }
507
508        /**
509         * 編集設定オブジェクトをセットします。
510         *
511         * @og.rev 5.3.6.0 (2011/06/01) 新規追加
512         *
513         * @param config 編集設定オブジェクト
514         */
515        @Override       // Query
516        public void setEditConfig( final DBEditConfig config ) {
517                this.config = config;
518        }
519
520        /**
521         * 編集設定オブジェクトを取得します。
522         *
523         * @og.rev 5.3.6.0 (2011/06/01) 新規追加
524         *
525         * @return 編集設定オブジェクト
526         */
527        protected DBEditConfig getEditConfig() {
528                return config;
529        }
530
531        //////////////////////////////////////////////////////////////////////////
532        //
533        //       継承時にサブクラスから使用するメソッド類( protected )
534        //
535        //////////////////////////////////////////////////////////////////////////
536
537        /**
538         * ResultSet を DBTableModelに割り当てます。
539         *
540         * 毎回、検索毎に DBTableModel にコピーするイメージです。
541         * ResulSet 以外のオブジェクトから、DBTableModelを作成する場合は、
542         * このメソッドをオーバーライドします。
543         *
544         * このメソッドは、execute からのみ呼び出されます。
545         * それ以外からは呼出し出来ません。
546         *
547         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
548         * @og.rev 3.3.3.3 (2003/08/06) カラムのラベル名を、大文字に変換する。
549         * @og.rev 3.8.5.0 (2006/03/02) CLOB カラムかどうかを判定しCLOBの場合は、Clob オブジェクトから文字列を取り出します。
550         * @og.rev 3.8.8.8 (2007/05/11) ROWID対応(小数点対応 "0.3" が ".3" と表示される対策)
551         * @og.rev 4.0.0.0 (2006/01/31) CLOB カラムかどうかを判定しCLOBの場合は、ストリームから値を取り出します。
552         * @og.rev 5.3.6.0 (2011/06/01) DBTableModel作成処理をDBTableModelUtilに移動&集計機能対応
553         * @og.rev 6.3.6.1 (2015/08/28) close(),realClose() 廃止。Queryはキャッシュしません。
554         *
555         * @param       resultSet ResultSetオブジェクト
556         */
557        protected void createTableModel( final ResultSet resultSet ) {
558                try {
559                        if( config == null ) {
560                                table = DBTableModelUtil.makeDBTable( resultSet, getSkipRowCount(), maxRowCount, resource );
561                        }
562                        else {
563                                table = DBTableModelUtil.makeEditDBTable( resultSet, getSkipRowCount(), maxRowCount, resource, config );
564                        }
565
566                        setExecuteCount( table.getRowCount() );
567                }
568                catch( final SQLException ex ) {
569                        final String errMsg = "テーブルモデルを作成できませんでした。";
570                        throw new HybsSystemException( errMsg,ex );             // 3.5.5.4 (2004/04/15) 引数の並び順変更
571                }
572        }
573
574        /**
575         * ConnectionFactory.connection( String ); を利用して、Connection
576         * オブジェクトを取り出します。
577         *
578         * コネクションプールが一杯の場合は、即エラーになります。
579         *
580         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
581         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為、ApplicationInfoオブジェクトを設定
582         * @og.rev 5.1.9.0 (2010/08/01) transaction 属性追加。
583         * @og.rev 6.3.6.1 (2015/08/28) transaction 属性廃止。内部のConnectionを返します。
584         *
585         * @return      コネクション
586         */
587        protected Connection getConnection() {
588                return connection;
589        }
590
591        /**
592         * この接続が、PreparedStatement#getParameterMetaData() を使用するかどうかを判定します。
593         *
594         * ConnectionFactory#useParameterMetaData(String) の結果を返します。(postgreSQL対応)
595         *
596         * ※ 暫定処理です。もっと、良い方法を考える必要があります。
597         *
598         * @og.rev 5.3.8.0 (2011/08/01) 新規追加
599         * @og.rev 6.3.6.1 (2015/08/28) 内部変数にconnIDが無くなったため、直接所得することになりました。
600         * @og.rev 6.4.2.0 (2016/01/29) ex.printStackTrace() を、ThrowUtil#ogStackTrace(Throwable) に置き換え。
601         *
602         * @return      使用する場合:true / その他:false
603         * @see org.opengion.fukurou.db.ConnectionFactory#useParameterMetaData(String)
604         */
605        protected boolean useParameterMetaData() {
606                try {
607                        return "PostgreSQL".equalsIgnoreCase( connection.getMetaData().getDatabaseProductName() );
608                }
609                catch( final Throwable th ) {
610                        System.err.println( ThrowUtil.ogStackTrace( th ) );                             // 6.4.2.0 (2016/01/29)
611                }
612                return false ;
613        }
614
615        //////////////////////////////////////////////////////////////////////////
616        //
617        //       Object クラスのオーバーライド部分
618        //
619        //////////////////////////////////////////////////////////////////////////
620
621        /**
622         * オブジェクトの識別子として、最後のクエリーを返します。
623         *
624         * @return      最後のクエリー
625         * @og.rtnNotNull
626         */
627        @Override
628        public String toString() {
629                return  "LastQuery  :[" + getStatement() + "] ";
630        }
631}