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.hayabusa.db;
017
018 import java.sql.ResultSet;
019 import java.sql.ResultSetMetaData;
020 import java.sql.SQLException;
021 import java.sql.Types;
022 import java.util.Locale;
023
024 import org.opengion.fukurou.db.DBUtil;
025 import org.opengion.fukurou.db.Transaction;
026 import org.opengion.fukurou.db.TransactionReal;
027 import org.opengion.fukurou.util.ApplicationInfo;
028 import org.opengion.fukurou.util.ErrorMessage;
029 import org.opengion.fukurou.util.StringUtil;
030 import org.opengion.hayabusa.common.HybsSystem;
031 import org.opengion.hayabusa.common.HybsSystemException;
032 import org.opengion.hayabusa.resource.LabelData;
033 import org.opengion.hayabusa.resource.ResourceManager;
034
035 /**
036 * ãƒ??タベã?ス関連の便利なメソãƒ?ƒ‰を集めた簡易ユーãƒ?‚£リãƒ?‚£ークラスですã?
037 * 全てのメソãƒ?ƒ‰は、static メソãƒ?ƒ‰になってã�?�¾すã?
038 *
039 * @og.rev 2.1.1.1 (2002/11/15) Serializable インターフェースを削除するã€?
040 * @og.rev 4.0.0.0 (2007/10/16) 名称変更(DBUtil â‡?DBTableModelUtil) DBアクセス関係ã?メソãƒ?ƒ‰はfukurou/db/DBUtilに移å‹?
041 * @og.group ?¤?¢/Shell制御
042 *
043 * @version 4.0
044 * @author Kazuhiko Hasegawa
045 * @since JDK5.0,
046 */
047 public final class DBTableModelUtil {
048 /**
049 * インスタンスを作らなã�??で、コンストラクタは、private に設定しますã?
050 */
051 private DBTableModelUtil() {}
052
053 /**
054 * 初期ãƒ??タベã?スに接続して、Queryを実行しますã?
055 * スãƒ??トメントと引数により、Prepared クエリーの検索のみ実行しますã?
056 * 結果は,DBTableModel として返されますã?
057 *
058 * @og.rev 3.0.0.0 (2002/12/25) 新規追åŠ?
059 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得ã?為,ApplicationInfoオブジェクトを設å®?
060 * @og.rev 4.0.0.0 (2005/01/31) lang â‡?ResourceManager へ変更
061 * @og.rev 4.0.0.0 (2007/10/10) dbid の初期値をã?"DEFAULT" から null に変更
062 *
063 * @param stmt スãƒ??トメント文字å?
064 * @param args オブジェクトã?引数配å?
065 * @param resource リソースマネージャー
066 * @param appInfo アプリæƒ??オブジェクãƒ?
067 *
068 * @return 検索結果の配å?
069 */
070 public static DBTableModel makeDBTable( final String stmt ,final String[] args, final ResourceManager resource, final ApplicationInfo appInfo ) {
071 // return makeDBTable( stmt ,args,resource,appInfo,"DEFAULT" ); // 4.0.0 (2005/01/31)
072 return makeDBTable( stmt ,args,resource,appInfo,null );
073 }
074
075 /**
076 * 検索するãƒ??タベã?スを指定して、Queryを実行しますã?
077 * スãƒ??トメントと引数により、Prepared クエリーの検索のみ実行しますã?
078 * 結果は,DBTableModel として返されますã?
079 * 検索以外ã?SQLも実行できますã?結果は、null を返しますã?
080 *
081 * @og.rev 3.0.0.0 (2002/12/25) 新規追åŠ?
082 * @og.rev 3.0.0.1 (2003/02/14) ヘッãƒ??、フãƒ?‚¿ーæƒ??ã�?null のときã?処ç�?¿½åŠ??
083 * @og.rev 3.5.6.0 (2004/06/18) nullに対する無é§?�ª比è¼?‚’削除しますã?
084 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得ã?為,ApplicationInfoオブジェクトを設å®?
085 * @og.rev 4.0.0.0 (2005/01/31) lang â‡?ResourceManager へ変更
086 * @og.rev 5.1.9.0 (2010/08/01) Transaction 対å¿?
087 * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更
088 * @og.rev 5.3.8.0 (2011/08/01) Transaction発生ç®?‰€でclose()
089 *
090 * @param stmt スãƒ??トメント文字å?
091 * @param args オブジェクトã?引数配å?
092 * @param resource リソースマネージャー
093 * @param appInfo アプリæƒ??オブジェクãƒ?
094 * @param dbid 接続å?ID
095 *
096 * @return 検索結果の配å?
097 */
098 public static DBTableModel makeDBTable( final String stmt ,final String[] args ,
099 final ResourceManager resource, final ApplicationInfo appInfo, final String dbid ) {
100 if( stmt == null || stmt.length() == 0 ) { return null; }
101
102 DBTableModel table = null;
103
104 Query query = QueryFactory.newInstance( "JDBCPrepared" );
105
106 ErrorMessage errMessage = null;
107 Transaction tran = null;
108 try {
109 // Transaction tran = new TransactionReal( dbid,appInfo ); // 5.1.9.0 (2010/08/01) Transaction 対å¿?
110 // Transaction tran = new TransactionReal( appInfo ); // 5.3.7.0 (2011/07/01) 引数変更
111 tran = new TransactionReal( appInfo ); // 5.3.8.0 (2011/08/01) Transaction発生ç®?‰€でclose()
112 query.setTransaction( dbid,tran ); // 5.1.9.0 (2010/08/01) Transaction 対å¿?
113 // query.setConnectionID( dbid );
114 query.setResourceManager( resource ); // 4.0.0 (2005/01/31)
115 query.setStatement( stmt );
116 query.execute( args );
117 int errCode = query.getErrorCode();
118 int executeCount = query.getExecuteCount();
119 if( errCode < ErrorMessage.NG && executeCount >= 0 ) { // 異常以外ã?場å�?
120 table = query.getDBTableModel();
121 // if( query.getUpdateFlag() ) { query.commit(); }
122 if( query.isUpdate() ) { query.commit(); }
123 }
124 else {
125 errMessage = query.getErrorMessage();
126 }
127 }
128 catch( HybsSystemException ex ) {
129 if( query != null ) { query.rollback(); }
130 throw ex;
131 }
132 finally {
133 // if( query != null ) { query.close(); }
134 QueryFactory.close( query );
135 if( tran != null ) { tran.close(); } // 5.3.8.0 (2011/08/01) Transaction発生ç®?‰€でclose()
136 }
137
138 if( errMessage != null ) {
139 throw new HybsSystemException( errMessage.toString() );
140 }
141
142 return table;
143 }
144
145 /**
146 * 空の DBTableModelオブジェクトを作æ?しますã?
147 * これは、本来、ファクトリクラスで作æ?すべきですが、簡易作æ?メソãƒ?ƒ‰として
148 * DBUtil の static メソãƒ?ƒ‰として実è£?�—ますã?
149 *
150 * @og.rev 4.0.0.0 (2005/01/31) 新規追åŠ?
151 *
152 * @return DBTableModelオブジェクãƒ?
153 */
154 public static DBTableModel newDBTable() {
155 return new DBTableModelImpl();
156 }
157
158 /**
159 * カラãƒ?��の配å?及ã?ãƒ??タの2次å…??列からDBãƒ??ブルモãƒ?ƒ«を作æ?しますã?
160 * カラãƒ?��がセãƒ?ƒˆされてã�?�ªã�?‹¥しくはãƒ??タがセãƒ?ƒˆされてã�?�ªã�??合ã?、nullを返しますã?
161 *
162 * @og.rev 4.2.1.0 (2008/04/26) 新規追åŠ?
163 *
164 * @param clms カラãƒ?��の配å?
165 * @param vals 値の配å?
166 * @param resource リソースマネージャー
167 *
168 * @return DBãƒ??ブルモãƒ?ƒ«
169 */
170 public static DBTableModel makeDBTable( final String[] clms, final String[][] vals, final ResourceManager resource ) {
171 if( clms == null || clms.length == 0
172 || vals == null || vals.length == 0 || vals[0] == null || vals[0].length == 0 ) {
173 return null;
174 }
175
176 if( clms.length != vals[0].length ) {
177 // throw new HybsSystemException( "キーのカラãƒ?•°とãƒ??タのカラãƒ?•°がä¸??してã�?�¾せん" );
178 String errMsg = "キーのカラãƒ?•°とãƒ??タのカラãƒ?•°がä¸??してã�?�¾せんã€?
179 + HybsSystem.CR
180 + " clms.length=[" + clms.length + "] vals.length=[" + vals[0].length + "]"
181 + " clms=" + StringUtil.array2csv( clms ) + HybsSystem.CR
182 + " vals=" + StringUtil.array2csv( vals[0] ) ; // 5.1.8.0 (2010/07/01) errMsg 修正
183 throw new HybsSystemException( errMsg );
184 }
185
186 int numberOfColumns = clms.length;
187 DBTableModel table = newDBTable() ;
188 table.init( numberOfColumns );
189
190 DBColumn[] dbColumn = new DBColumn[numberOfColumns];
191 for( int column=0; column<numberOfColumns; column++ ) {
192 dbColumn[column] = resource.makeDBColumn( clms[column] );
193 table.setDBColumn( column,dbColumn[column] );
194 }
195
196 int numberOfRows = vals.length;
197 for( int row=0; row<numberOfRows; row++ ) {
198 table.addColumnValues( vals[row] );
199 }
200
201 return table;
202 }
203
204 /**
205 * 検索結果オブジェクトからDBãƒ??ブルモãƒ?ƒ«を作æ?しますã?
206 * 検索結果オブジェクトまたã?リソースオブジェクトがセãƒ?ƒˆされてã�?�ªã�??合ã?、nullを返しますã?
207 *
208 * @og.rev 5.3.6.0 (2011/06/01) 新規追åŠ?
209 * @og.rev 5.5.5.4 (2012/08/18) TIMESTAMP 型もCLOBと同様に処ç�?‚’åˆ?�‘るã?
210 *
211 * @param result 検索結果オブジェクãƒ?
212 * @param skipRowCount 読み飛ã?し件数
213 * @param maxRowCount æœ?¤§検索件数
214 * @param resource リソースマネージャー
215 *
216 * @return DBãƒ??ブルモãƒ?ƒ«
217 * @throws SQLException ãƒ??タベã?スアクセスエラー
218 */
219 public static DBTableModel makeDBTable( final ResultSet result, final int skipRowCount, final int maxRowCount, final ResourceManager resource ) throws SQLException {
220 if( result == null || resource == null ) { return null; }
221
222 ResultSetMetaData metaData = result.getMetaData();
223
224 int numberOfColumns = metaData.getColumnCount();
225
226 DBTableModel table = DBTableModelUtil.newDBTable() ;
227 table.init( numberOfColumns );
228
229 // é ?›®名,é?目タイプ,é?目サイズ?Œ書込みフラグを設定するã?
230 DBColumn[] dbColumn = new DBColumn[numberOfColumns];
231
232 // 3.8.5.0 (2006/03/02) CLOB/ROWID などのカラãƒ?�‹どã�?�‹を判定しますã?
233 boolean isOther = false;
234 int[] types = new int[numberOfColumns];
235
236 for( int column=0; column<numberOfColumns; column++ ) {
237 String name = (metaData.getColumnLabel(column+1)).toUpperCase(Locale.JAPAN) ;
238 dbColumn[column] = resource.getDBColumn( name );
239 if( dbColumn[column] == null ) {
240 LabelData labelData = resource.getLabelData( name );
241 dbColumn[column] = makeDBColumn( name,labelData,metaData,column,resource.getLang() );
242 }
243 table.setDBColumn( column,dbColumn[column] );
244
245 // 3.8.5.0 (2006/03/02) CLOB カラãƒ?�‹どã�?�‹を判定しますã?
246 // 5.5.5.4 (2012/08/18) TIMESTAMP 型もCLOBと同様に処ç�?‚’åˆ?�‘るã?
247 // types[column] = metaData.getColumnType(column+1);
248 int clmType = metaData.getColumnType(column+1);
249 types[column] = clmType;
250 // if( types[column] == Types.CLOB || types[column] == Types.ROWID ) { // JDK 6.0以é™?ROWID
251 if( clmType == Types.CLOB || clmType == Types.ROWID || clmType == Types.TIMESTAMP ) { // JDK 6.0以é™?ROWID
252 isOther = true;
253 }
254 }
255
256 // ãƒ??タ部の設å®?
257 int numberOfRows = 0;
258 while( numberOfRows < skipRowCount && result.next() ) {
259 // 注æ„?resultSet.next() をå?に判定するとå¿?�š?‘件読み飛ã?してしまã�??
260 numberOfRows ++ ;
261 }
262 // resultSet.absolute( getSkipRowCount() );
263 numberOfRows = 0;
264
265 // 3.8.5.1 (2006/05/08) 行å?のループなのでã€?CLOB 使用可否でループをåˆ?�‘るã?
266 if( isOther ) {
267 while( numberOfRows < maxRowCount && result.next() ) {
268 numberOfRows ++ ;
269 String[] columnValues = new String[numberOfColumns];
270 for( int column=0; column<numberOfColumns; column++ ) {
271 // 5.3.6.0 (2011/06/01) メソãƒ?ƒ‰åŒ?
272 columnValues[column] = DBUtil.getValue( result, column, types[column] );
273 }
274 table.addColumnValues( columnValues );
275 }
276 }
277 else {
278 while( numberOfRows < maxRowCount && result.next() ) {
279 numberOfRows ++ ;
280 String[] columnValues = new String[numberOfColumns];
281 for( int column=0; column<numberOfColumns; column++ ) {
282 Object obj = result.getObject(column+1);
283 columnValues[column] = ( obj == null ? "" : String.valueOf( obj ) );
284 }
285 table.addColumnValues( columnValues );
286 }
287 }
288
289 // æœ?¤§件数がã?è¶?�ˆたå?合でかつ次のãƒ??タがあるå?合ã?、オーバã?フロー
290 if( numberOfRows >= maxRowCount && result.next() ) {
291 table.setOverflow( true );
292 }
293
294 return table;
295 }
296
297 /**
298 * 検索結果オブジェクトからエãƒ?‚£ãƒ?ƒˆ設定に基づã�?�¦変換されたDBãƒ??ブルモãƒ?ƒ«を作æ?しますã?
299 * 検索結果オブジェクトまたã?リソースオブジェクトまたã?エãƒ?‚£ãƒ?ƒˆ設定オブジェクトがセãƒ?ƒˆされてã�?�ªã�??合ã?、nullを返しますã?
300 *
301 * @og.rev 5.3.6.0 (2011/06/01) 新規追åŠ?
302 *
303 * @param result 検索結果オブジェクãƒ?
304 * @param skipRowCount 読み飛ã?し件数
305 * @param maxRowCount æœ?¤§検索件数
306 * @param resource リソースマネージャー
307 * @param config エãƒ?‚£ãƒ?ƒˆ設定オブジェクãƒ?
308 *
309 * @return DBãƒ??ブルモãƒ?ƒ«
310 * @throws SQLException ãƒ??タベã?スアクセスエラー
311 */
312 public static DBTableModel makeEditDBTable( final ResultSet result, final int skipRowCount, final int maxRowCount, final ResourceManager resource, final DBEditConfig config ) throws SQLException {
313 if( result == null || resource == null ) { return null; }
314 DBTableModel table = new DBTableModelEditor();
315 ((DBTableModelEditor)table).create( result, skipRowCount, maxRowCount, resource, config );
316 return table;
317 }
318
319 /**
320 * ResultSetMetaData から、DBColumn オブジェクトを作æ?しますã?
321 *
322 * DBColumn オブジェクãƒ?がリソースファイルに定義されてã�?�ªã�??合にã€?
323 * ãƒ??タベã?スの検索結果のメタãƒ??タを利用して、DBColumn オブジェクトを
324 * 作æ?しますã?
325 *
326 * @og.rev 3.4.0.0 (2003/09/01) 表示パラメータ、編é›?ƒ‘ラメータ、文字パラメータの追åŠ??
327 * @og.rev 3.4.0.2 (2003/09/05) DBType のãƒ?ƒ•ォルトå?をã?'X' から 'XK' に変更しますã?
328 * @og.rev 3.6.0.7 (2004/11/06) DBColumn の official属æ?追åŠ?
329 * @og.rev 4.0.0.0 (2005/01/31) lang 変数を取å¾?
330 * @og.rev 5.3.6.0 (2011/06/01) AbstractQueryから移å‹?
331 *
332 * @param name カラãƒ?��
333 * @param labelData LabelDataオブジェクãƒ?
334 * @param metaData ResultSetMetaDataオブジェクãƒ?
335 * @param column カラãƒ?•ª号
336 * @param lang è¨?ª?
337 *
338 * @return DBColumnオブジェクãƒ?
339 */
340 public static DBColumn makeDBColumn( final String name,final LabelData labelData,
341 final ResultSetMetaData metaData,final int column,final String lang ) {
342 final DBColumn dbColumn ;
343
344 try {
345 String clsName = type2ClassName( metaData.getColumnType(column+1) );
346 int size = metaData.getColumnDisplaySize(column+1);
347 if( size == 0 ) { size = 60; }
348 boolean writable = metaData.isWritable(column+1);
349 String dbType = ( "NUMBER".equals( clsName )) ? "S9" : "XK" ;
350 String defValue = ( "NUMBER".equals( clsName )) ? "0" : "" ;
351 DBColumnConfig config = new DBColumnConfig(
352 lang, // è¨?ª?
353 name, // カラãƒ?��
354 labelData, // カラãƒ??ラベルãƒ??タオブジェクãƒ?
355 clsName , // カラãƒ??クラスを文字å?にした名称
356 String.valueOf( size ) , // カラãƒ??æ–?—桁数
357 String.valueOf( writable ) , // カラãƒ?�Œ書き込み可能かどã�?�‹
358 null , // ãƒ??タの表示用レンãƒ?ƒ©ー
359 null , // ãƒ??タの編é›?”¨エãƒ?‚£ター
360 null , // メニューのé ?›®コードデータオブジェクãƒ?
361 dbType , // ãƒ??タのタイãƒ?
362 defValue, // ãƒ??タのãƒ?ƒ•ォルトå?
363 null , // 表示用レンãƒ?ƒ©ーのパラメータ
364 null , // 編é›?”¨エãƒ?‚£ターのパラメータ
365 null , // ãƒ??タのタイプã?パラメータ
366 null , // カラãƒ?ƒール
367 false, // 正式なカラãƒ?‚ªブジェクトかどã�?�‹
368 null // ãƒ??タベã?ス接続å?ID
369 );
370
371 dbColumn = new DBColumn( config ); // 4.0.0 (2005/01/31)
372
373 }
374 catch( SQLException ex ) {
375 String errMsg = "DBColumn を作æ?できませんでした。name=[" + name + " , label=[" + labelData + "]";
376 throw new HybsSystemException( errMsg,ex ); // 3.5.5.4 (2004/04/15) 引数の並びé ?¤‰更
377 }
378 catch( RuntimeException ex2 ) {
379 String errMsg = "予期せぬエラーが発生しました。name=[" + name + " , label=[" + labelData + "]";
380 throw new HybsSystemException( errMsg,ex2 ); // 3.6.0.0 (2004/09/17)
381 }
382
383 return dbColumn;
384 }
385
386 /**
387 * カラãƒ??タイプを表現するæ–?—å?値を返しますã?
388 *
389 * こã?æ–?—å?を用ã�?�¦、CCSファイルでタイプごとの表示方法を
390 * æŒ?®šすることができますã?
391 *
392 * @og.rev 2.1.1.1 (2002/11/15) そã?他ã?ケースをã?VARCHAR2 を返すように修正ã€?
393 * @og.rev 4.0.0.0 (2006/01/31) CLOB を追åŠ?
394 * @og.rev 5.3.6.0 (2011/06/01) AbstractQueryから移å‹?
395 * @og.rev 5.5.5.4 (2012/08/18) DECIMAL,TIMESTAMP を追åŠ?
396 *
397 * @param type タイプ番号
398 *
399 * @return カラãƒ??タイプを表現するæ–?—å?値
400 * @see java.sql.Types
401 */
402 private static String type2ClassName( final int type ) {
403 final String rtn ;
404
405 switch( type ) {
406 case Types.CHAR:
407 case Types.VARCHAR:
408 case Types.BIT:
409 rtn = "VARCHAR2"; break;
410 case Types.LONGVARCHAR: // 4.0.0 (2006/01/31)
411 rtn = "LONG"; break;
412 case Types.TINYINT:
413 case Types.SMALLINT:
414 case Types.INTEGER:
415 case Types.NUMERIC:
416 case Types.BIGINT:
417 case Types.FLOAT:
418 case Types.DOUBLE:
419 case Types.REAL:
420 case Types.DECIMAL: // 5.5.5.4 (2012/08/18)
421 rtn = "NUMBER"; break;
422 case Types.DATE:
423 case Types.TIMESTAMP: // 5.5.5.4 (2012/08/18)
424 rtn = "DATE"; break;
425 case Types.CLOB: // 4.0.0 (2006/01/31)
426 rtn = "CLOB"; break;
427 default:
428 rtn = "NONE"; break;
429 }
430
431 return rtn;
432 }
433 }