001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.fukurou.db; 017 018import java.io.IOException; 019import java.io.Reader; 020import java.sql.Struct; // 6.3.3.0 (2015/07/25) 021import java.sql.Clob; 022import java.sql.ResultSet; 023import java.sql.ResultSetMetaData; 024import java.sql.SQLException; 025import java.sql.Types; 026import java.sql.Date; 027import java.sql.Timestamp; 028import java.util.Locale; 029import java.util.List; // 6.3.3.0 (2015/07/25) 030import java.util.ArrayList; // 6.3.3.0 (2015/07/25) 031import java.util.Map; // 6.8.6.0 (2018/01/19) 032import java.util.HashMap; // 6.8.6.0 (2018/01/19) 033 034import oracle.jdbc.OracleStruct; // 6.3.8.0 (2015/09/11) 035import oracle.jdbc.OracleTypeMetaData; // 6.3.8.0 (2015/09/11) 036 037import org.opengion.fukurou.system.OgRuntimeException ; // 6.4.2.0 (2016/01/29) 038import org.opengion.fukurou.system.DateSet; // 6.4.2.0 (2016/01/29) 039import org.opengion.fukurou.system.Closer; 040import static org.opengion.fukurou.system.HybsConst.CR; // 6.1.0.0 (2014/12/26) refactoring 041 042/** 043 * ResultSet のデータ処理をまとめたクラスです。 044 * ここでは、ResultSetMetaData から、カラム数、カラム名(NAME列)、 045 * Type属性を取得し、ResultSet で、値を求める時に、Object型の 046 * 処理を行います。 047 * Object型としては、CLOB、ROWID、TIMESTAMP 型のみ取り扱っています。 048 * STRUCTタイプもサポートしますが、1レベルのみとします。(6.3.3.0 (2015/07/25)) 049 * 050 * @og.rev 6.0.4.0 (2014/11/28) 新規作成 051 * @og.rev 6.3.3.0 (2015/07/25) STRUCTタイプの対応 052 * @og.group DB制御 053 * 054 * @version 6.0 055 * @author Kazuhiko Hasegawa 056 * @since JDK6.0, 057 */ 058public class ResultSetValue implements AutoCloseable { 059 private static final int BUFFER_MIDDLE = 10000; // 6.3.3.0 (2015/07/25) 060 061 private final ResultSet resultSet ; // 内部で管理する ResultSet オブジェクト 062 private final List<ColumnInfo> clmInfos ; 063 064 private boolean skipNext ; // STRUCT 使用時に、next() してデータ構造を取得するため。 065 private boolean firstNext ; // STRUCT 使用時に、next() してデータ構造を取得するため。 066 067 /** 068 * ResultSet を引数にとるコンストラクタ 069 * 070 * ここで、カラムサイズ、カラム名、java.sql.Types の定数定義 を取得します。 071 * STRUCTタイプもサポートしますが、1レベルのみとします。 072 * つまり、Object型のカラムに、Object型を定義した場合、ここでは取り出すことができません。 073 * また、Object型は、継承関係を構築できるため、個々のオブジェクトの要素数は異なります。 074 * 一番最初のレコードのオブジェクト数を元に、算出しますので、ご注意ください。 075 * 076 * @og.rev 6.0.4.0 (2014/11/28) 新規作成 077 * @og.rev 6.3.3.0 (2015/07/25) STRUCTタイプの対応 078 * @og.rev 6.3.8.0 (2015/09/11) Oracle Database 12cリリース1 (12.1)以降、StructDescriptor は非推奨 079 * 080 * @param res 内部で管理するResultSetオブジェクト 081 * @throws java.sql.SQLException データベース・アクセス・エラーが発生した場合 082 */ 083 public ResultSetValue( final ResultSet res ) throws SQLException { 084 resultSet = res; 085 086 final ResultSetMetaData metaData = resultSet.getMetaData(); 087 final int clmSize = metaData.getColumnCount(); 088 089 clmInfos = new ArrayList<>(); 090 091 for( int i=0; i<clmSize; i++ ) { 092 final int clmNo = i+1; 093 final int type = metaData.getColumnType( clmNo ); 094 final String name = metaData.getColumnLabel( clmNo ).toUpperCase(Locale.JAPAN) ; 095 if( type == Types.STRUCT ) { 096 if( !skipNext ) { // オブジェクト型を取得する為、データを取る必要がある。 097 skipNext = true; 098 firstNext = resultSet.next(); // 初めての next() の結果を保持(falseなら、データなし) 099 } 100 if( firstNext ) { 101 // 最初のオブジェクトのタイプを基準にする。 102 final Object obj = resultSet.getObject( clmNo ); 103 if( obj != null ) { 104 // 6.3.8.0 (2015/09/11) Oracle Database 12cリリース1 (12.1)以降、StructDescriptor は非推奨 105 final OracleTypeMetaData omd = ((OracleStruct)obj).getOracleMetaData(); 106 final ResultSetMetaData md = ((OracleTypeMetaData.Struct)omd).getMetaData(); 107 108 final int mdsize = md.getColumnCount(); 109 for( int j=0; j<mdsize; j++ ) { 110 final int objNo = j+1; 111 // カラム名.オブジェクトカラム名 112 final String name2 = name + '.' + md.getColumnLabel(objNo).toUpperCase(Locale.JAPAN); 113 final int type2 = md.getColumnType( objNo ); 114 final int size2 = md.getColumnDisplaySize( objNo ); 115 final boolean isWrit2 = md.isWritable( objNo ); 116 clmInfos.add( new ColumnInfo( name2,type2,size2,isWrit2,clmNo,j ) ); // ※ objNo でなく、「j」 117 } 118 } 119 } 120 } 121 else { 122 final int size = metaData.getColumnDisplaySize( clmNo ); 123 final boolean isWrit = metaData.isWritable( clmNo ); 124 clmInfos.add( new ColumnInfo( name,type,size,isWrit,clmNo,-1 ) ); // ※ objNo でなく、「-1」 125 } 126 } 127 } 128 129 /** 130 * ResultSetMetaData で求めた、カラム数を返します。 131 * 132 * @og.rev 6.0.4.0 (2014/11/28) 新規作成 133 * @og.rev 6.3.3.0 (2015/07/25) STRUCTタイプの対応 134 * 135 * @return カラム数(データの列数) 136 */ 137 public int getColumnCount() { 138 return clmInfos.size(); 139 } 140 141 /** 142 * カラム名配列を返します。 143 * 144 * 配列は、0から始まり、カラム数-1 までの文字型配列に設定されます。 145 * カラム名は、ResultSetMetaData#getColumnLabel(int) を toUpperCase した 146 * 大文字が返されます。 147 * 148 * @og.rev 6.0.4.0 (2014/11/28) 新規作成 149 * @og.rev 6.3.3.0 (2015/07/25) STRUCTタイプの対応 150 * 151 * @return カラム名配列 152 * @og.rtnNotNull 153 */ 154 public String[] getNames() { 155 return clmInfos.stream().map( info -> info.getName() ).toArray( String[]::new ); 156 } 157 158 /** 159 * カラム名配列に対応する カラム番号配列を返します。 160 * 161 * 引数のカラム名配列が、null の場合は、長さゼロの配列を返します。 162 * 指定のカラム名が存在しなかった場合は、アドレスに -1 がセットされます。 163 * 164 * @og.rev 6.8.6.0 (2018/01/19) 新規追加 165 * 166 * @param clmNms 値が参照されるカラム名配列(可変長引数) 167 * 168 * @return 指定されたセルのカラム番号配列。 169 * @og.rtnNotNull 170 */ 171 public int[] getColumnNos( final String[] clmNms ) { 172 return getColumnNos( clmNms, false ); 173 } 174 175 /** 176 * カラム名配列に対応する カラム番号配列を返します。 177 * 178 * 引数のカラム名配列が、null の場合は、長さゼロの配列を返します。 179 * 180 * 指定のカラム名が存在しなかった場合の動作は、useThrow 引数で決まります。 181 * useThrow が、true の場合は、カラム名が存在しない場合は、 HybsSystemException を 182 * throw します。useThrow が、false の場合は、カラム名が存在しない場合は、 183 * アドレスに -1 がセットされます。 184 * 185 * @og.rev 6.8.6.0 (2018/01/19) 新規追加 186 * @og.rev 6.9.0.2 (2018/02/13) カラム名が、"*" の場合の対応 187 * 188 * @param clmNms 値が参照されるカラム名配列(可変長引数) 189 * @param useThrow カラム名が存在しない場合に、Exception を throw するかどうか 190 * 191 * @return 指定されたセルのカラム番号配列。 192 * @og.rtnNotNull 193 */ 194 public int[] getColumnNos( final String[] clmNms,final boolean useThrow ) { 195 // 6.9.0.2 (2018/02/13) カラム名が、"*" の場合の対応 196 if( clmNms != null && clmNms.length == 1 && "*".equals( clmNms[0] ) ) { 197 final int[] clmNos = new int[clmInfos.size()]; 198 for( int i=0; i<clmInfos.size(); i++ ) { 199 clmNos[i] = 1; 200 } 201 return clmNos; 202 } 203 204 // 名前のMapを作成します。 205 final Map<String, Integer> nameMap = new HashMap<>(); 206 for( int i=0; i<clmInfos.size(); i++ ) { 207 nameMap.put( clmInfos.get(i).getName() , Integer.valueOf(i) ); // 名前とカラム番号 208 } 209 210 final int size = clmNms == null ? 0 : clmNms.length ; 211 212 final int[] clmNos = new int[size]; 213 for( int j=0; j<size; j++ ) { 214 final Integer ad = nameMap.get( clmNms[j] ); 215 if( ad == null ) { // カラム名が存在しない。 216 if( useThrow ) { 217 final String errMsg = "指定のカラム名が存在しません。 カラム名[" + j + "]=[" + clmNms[j] + "]" + CR 218 + " 引数カラム配列=[" + String.join( "," , clmNms ) + "]" + CR 219 + " 内部カラム列=[" + String.join( "," , nameMap.keySet() ) + "]"; 220 throw new OgRuntimeException( errMsg ); 221 } 222 clmNos[j] = -1; 223 } 224 else { 225 clmNos[j] = ad.intValue(); 226 } 227 } 228 229 return clmNos; 230 } 231 232 /** 233 * 指定のカラム番号のカラム名を返します。 234 * 235 * カラム名を取得する、カラム番号は、0から始まり、カラム数-1 までの数字で指定します。 236 * データベース上の、1から始まる番号とは、異なります。 237 * カラム名は、ResultSetMetaData#getColumnLabel(int) を toUpperCase した 238 * 大文字が返されます。 239 * 240 * @og.rev 6.0.4.0 (2014/11/28) 新規作成 241 * @og.rev 6.3.3.0 (2015/07/25) STRUCTタイプの対応 242 * 243 * @param clmNo カラム番号 (0から始まり、カラム数-1までの数字) 244 * @return 指定のカラム番号のカラム名 245 */ 246 public String getColumnName( final int clmNo ) { 247 return clmInfos.get( clmNo ).name ; 248 } 249 250 /** 251 * 指定のカラム番号のサイズを返します。 252 * 253 * カラムのサイズは、ResultSetMetaData#getColumnDisplaySize(int) の値です。 254 * 255 * @og.rev 6.0.4.0 (2014/11/28) 新規作成 256 * @og.rev 6.3.3.0 (2015/07/25) STRUCTタイプの対応 257 * 258 * @param clmNo カラム番号 (0から始まり、カラム数-1までの数字) 259 * @return 指定のカラム番号のサイズ 260 */ 261 public int getColumnDisplaySize( final int clmNo ) { 262 return clmInfos.get( clmNo ).size ; 263 } 264 265 /** 266 * 指定の書き込み可能かどうかを返します。 267 * 268 * カラムの書き込み可能かどうかは、ResultSetMetaData#isWritable(int) の値です。 269 * 270 * @og.rev 6.0.4.0 (2014/11/28) 新規作成 271 * @og.rev 6.3.3.0 (2015/07/25) STRUCTタイプの対応 272 * 273 * @param clmNo カラム番号 (0から始まり、カラム数-1までの数字) 274 * @return 書き込み可能かどうか 275 */ 276 public boolean isWritable( final int clmNo ) { 277 return clmInfos.get( clmNo ).isWrit ; 278 } 279 280 /** 281 * カーソルを現在の位置から順方向に1行移動します。 282 * 283 * ResultSet#next() を呼び出しています。 284 * 結果は,すべて文字列に変換されて格納されます。 285 * 286 * @og.rev 6.0.4.0 (2014/11/28) 新規作成 287 * @og.rev 6.3.3.0 (2015/07/25) STRUCTタイプの対応 288 * 289 * @return 新しい現在の行が有効である場合はtrue、行がそれ以上存在しない場合はfalse 290 * @see java.sql.ResultSet#next() 291 * @throws java.sql.SQLException データベース・アクセス・エラーが発生した場合、またはこのメソッドがクローズされた結果セットで呼び出された場合 292 */ 293 public boolean next() throws SQLException { 294 if( skipNext ) { skipNext = false; return firstNext; } // STRUCTタイプ取得時に、一度 next() している。 295 return resultSet.next(); 296 } 297 298 /** 299 * 現在のカーソル位置にあるレコードのカラム番号のデータを取得します。 300 * 301 * ResultSet#getObject( clmNo+1 ) を呼び出しています。 302 * 引数のカラム番号は、0から始まりますが、ResultSet のカラム順は、1から始まります。 303 * 指定は、0から始まるカラム番号です。 304 * 結果は,すべて文字列に変換されて返されます。 305 * また、null オブジェクトの場合も、ゼロ文字列に変換されて返されます。 306 * 307 * @og.rev 6.0.4.0 (2014/11/28) 新規作成: org.opengion.hayabusa.db.DBUtil#getValue( ResultSet , int , int ) から移動 308 * @og.rev 6.3.3.0 (2015/07/25) STRUCTタイプの対応 309 * 310 * @param clmNo カラム番号 (0から始まり、カラム数-1までの数字) 311 * @return 現在行のカラム番号のデータ(文字列) 312 * @throws java.sql.SQLException データベース・アクセス・エラーが発生した場合 313 */ 314 public String getValue( final int clmNo ) throws SQLException { 315 final ColumnInfo clmInfo = clmInfos.get( clmNo ) ; // 内部カラム番号に対応したObject 316 final int dbClmNo = clmInfo.clmNo ; // データベース上のカラム番号(+1済み) 317 318 final String val ; 319 final Object obj = resultSet.getObject( dbClmNo ); 320 321 if( obj == null ) { 322 val = ""; 323 } 324 else if( clmInfo.isStruct ) { 325 final Object[] attrs = ((Struct)obj).getAttributes(); 326 final int no = clmInfo.objNo; 327 val = no < attrs.length ? String.valueOf( attrs[no] ) : "" ; // 配列オーバーする場合は、""(ゼロ文字列) 328 // for( Object obj2 : attrs ) { System.out.println( obj2 ); } 329 } 330 else if( clmInfo.isObject ) { 331 switch( clmInfo.type ) { 332 case Types.CLOB : val = getClobData( (Clob)obj ) ; 333 break; 334 case Types.ROWID: val = resultSet.getString( dbClmNo ); 335 break; 336 case Types.TIMESTAMP : val = DateSet.getDate( ((Timestamp)obj).getTime() , "yyyyMMddHHmmss" ); 337 break; 338 default : val = String.valueOf( obj ); 339 break; 340 } 341 } 342 else { 343 val = String.valueOf( obj ); 344 } 345 346 return val ; 347 } 348 349 /** 350 * 現在のカーソル位置にあるレコードの全カラムデータを取得します。 351 * 352 * #getValue( clmNo ) を、0から、カラム数-1 まで呼び出して求めた文字列配列を返します。 353 * 354 * @og.rev 6.0.4.0 (2014/11/28) 新規作成 355 * @og.rev 6.3.3.0 (2015/07/25) STRUCTタイプの対応 356 * 357 * @return 現在行の全カラムデータの文字列配列 358 * @throws java.sql.SQLException データベース・アクセス・エラーが発生した場合 359 */ 360 public String[] getValues() throws SQLException { 361 final String[] vals = new String[clmInfos.size()]; 362 363 for( int i=0; i<vals.length; i++ ) { 364 vals[i] = getValue( i ); 365 } 366 367 return vals ; 368 } 369 370 /** 371 * タイプに応じて変換された、Numberオブジェクトを返します。 372 * 373 * 条件に当てはまらない場合は、null を返します。 374 * org.opengion.hayabusa.io.HybsJDBCCategoryDataset2 から移動してきました。 375 * これは、検索結果をグラフ化する為の 値を取得する為のメソッドですので、 376 * 数値に変換できない場合は、エラーになります。 377 * 378 * @og.rev 6.0.4.0 (2014/11/28) 新規作成: org.opengion.hayabusa.db.DBUtil#getNumber( int , Object ) から移動 379 * @og.rev 6.3.3.0 (2015/07/25) STRUCTタイプの対応 380 * 381 * @param clmNo カラム番号 (0から始まり、カラム数-1までの数字) 382 * @return Numberオブジェクト(条件に当てはまらない場合は、null) 383 * @see java.sql.Types 384 * @throws java.sql.SQLException データベース・アクセス・エラーが発生した場合 385 * @throws RuntimeException 数字変換できなかった場合。 386 */ 387 public Number getNumber( final int clmNo ) throws SQLException { 388 final ColumnInfo clmInfo = clmInfos.get( clmNo ) ; // 内部カラム番号に対応したObject 389 final int dbClmNo = clmInfo.clmNo ; // データベース上のカラム番号(+1済み) 390 391 Number value = null; 392 393 Object obj = resultSet.getObject( dbClmNo ); 394 if( obj != null ) { 395 if( clmInfo.isStruct ) { 396 final Object[] attrs = ((Struct)obj).getAttributes(); 397 final int no = clmInfo.objNo; 398 obj = no < attrs.length ? attrs[no] : null ; // 配列オーバーする場合は、null 399 if( obj == null ) { return value; } // 配列外 or 取出した結果が null の場合、処理を中止。 400 } 401 402 // switch( type[clmNo] ) { 403 switch( clmInfo.type ) { 404 case Types.TINYINT: 405 case Types.SMALLINT: 406 case Types.INTEGER: 407 case Types.BIGINT: 408 case Types.FLOAT: 409 case Types.DOUBLE: 410 case Types.DECIMAL: 411 case Types.NUMERIC: 412 case Types.REAL: { 413 value = (Number)obj; 414 break; 415 } 416 case Types.DATE: 417 case Types.TIME: { 418 value = Long.valueOf( ((Date)obj).getTime() ); 419 break; 420 } 421 // 5.6.2.1 (2013/03/08) Types.DATE と Types.TIMESTAMP で処理を分けます。 422 case Types.TIMESTAMP: { 423 value = Long.valueOf( ((Timestamp)obj).getTime() ); 424 break; 425 } 426 case Types.CHAR: 427 case Types.VARCHAR: 428 case Types.LONGVARCHAR: { 429 final String str = (String)obj; 430 try { 431 value = Double.valueOf(str); 432 } 433 catch( final NumberFormatException ex) { 434 final String errMsg = "数字変換できませんでした。in=" + str 435 + CR + ex.getMessage() ; 436 throw new OgRuntimeException( errMsg,ex ); 437 // suppress (value defaults to null) 438 } 439 break; 440 } 441 default: 442 // not a value, can't use it (defaults to null) 443 break; 444 } 445 } 446 return value; 447 } 448 449 /** 450 * カラムのタイプを表現する文字列値を返します。 451 * 452 * この文字列を用いて、CCSファイルでタイプごとの表示方法を 453 * 指定することができます。 454 * 現時点では、VARCHAR2,LONG,NUMBER,DATE,CLOB,NONE のどれかにあてはめます。 455 * 456 * @og.rev 6.0.4.0 (2014/11/28) 新規作成: org.opengion.hayabusa.db.DBUtil#type2ClassName( int ) から移動 457 * @og.rev 6.3.3.0 (2015/07/25) STRUCTタイプの対応 458 * 459 * @param clmNo カラム番号 (0から始まり、カラム数-1までの数字) 460 * @return カラムのタイプを表現する文字列値 461 * @see java.sql.Types 462 */ 463 public String getClassName( final int clmNo ) { 464 final String rtn ; 465 466 switch( clmInfos.get( clmNo ).type ) { 467 case Types.CHAR: 468 case Types.VARCHAR: 469 case Types.BIT: 470 rtn = "VARCHAR2"; break; 471 case Types.LONGVARCHAR: 472 rtn = "LONG"; break; 473 case Types.TINYINT: 474 case Types.SMALLINT: 475 case Types.INTEGER: 476 case Types.NUMERIC: 477 case Types.BIGINT: 478 case Types.FLOAT: 479 case Types.DOUBLE: 480 case Types.REAL: 481 case Types.DECIMAL: 482 rtn = "NUMBER"; break; 483 case Types.DATE: 484 case Types.TIME: 485 case Types.TIMESTAMP: 486 rtn = "DATE"; break; 487 case Types.CLOB: 488 rtn = "CLOB"; break; 489 case Types.STRUCT: // 6.3.3.0 (2015/07/25) 内部分解されない2レベル以上の場合のみ 490 rtn = "STRUCT"; break; 491 default: 492 rtn = "NONE"; break; 493 } 494 495 return rtn; 496 } 497 498 /** 499 * try-with-resourcesブロックで、自動的に呼ばれる AutoCloseable の実装。 500 * 501 * コンストラクタで渡された ResultSet を close() します。 502 * 503 * @og.rev 6.4.2.1 (2016/02/05) 新規作成。try-with-resourcesブロックで、自動的に呼ばれる AutoCloseable の実装。 504 * 505 * @see java.lang.AutoCloseable#close() 506 */ 507 @Override // AutoCloseable 508 public void close() { 509 Closer.resultClose( resultSet ); 510 } 511 512 /** 513 * Clob オブジェクトから文字列を取り出します。 514 * 515 * @og.rev 6.0.4.0 (2014/11/28) 新規作成: org.opengion.hayabusa.db.DBUtil#getClobData( Clob ) から移動 516 * 517 * @param clobData Clobオブジェクト 518 * @return Clobオブジェクトから取り出した文字列 519 * @throws SQLException データベースアクセスエラー 520 * @throws RuntimeException 入出力エラーが発生した場合 521 * @og.rtnNotNull 522 */ 523 private String getClobData( final Clob clobData ) throws SQLException { 524 if( clobData == null ) { return ""; } 525 526 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); 527 528 Reader reader = null; 529 try { 530 reader = clobData.getCharacterStream(); 531 final char[] ch = new char[BUFFER_MIDDLE]; // char配列とBuilderの初期値は無関係。 532 int len ; 533 while( (len = reader.read( ch )) >= 0 ) { 534 buf.append( ch,0,len ); 535 } 536 } 537 catch( final IOException ex ) { 538 final String errMsg = "CLOBデータの読み込みに失敗しました。" 539 + ex.getMessage() ; 540 throw new OgRuntimeException( errMsg,ex ); 541 } 542 finally { 543 Closer.ioClose( reader ); 544 } 545 return buf.toString(); 546 } 547 548 /** 549 * 各種カラム属性の管理を、クラスで行うようにします。 550 * 551 * @og.rev 6.3.3.0 (2015/07/25) STRUCTタイプの対応 552 * 553 * @param clobData Clobオブジェクト 554 * @return Clobオブジェクトから取り出した文字列 555 */ 556 private static final class ColumnInfo { 557 private final String name ; // カラム名(ResultSetMetaData#getColumnLabel(int) の toUpperCase) 558 private final int type ; // java.sql.Types の定数定義 559 private final int size ; // カラムサイズ(ResultSetMetaData#getColumnDisplaySize(int)) 560 private final boolean isWrit ; // 書き込み許可(ResultSetMetaData#isWritable(int)) 561 private final int clmNo ; // ResultSet での元のカラムNo( 1から始まる番号 ) 562 private final int objNo ; // STRUCT での配列番号( 0から始まる番号 ) 563 private final boolean isStruct ; // オリジナルのタイプが、Struct型 かどうか。 564 private final boolean isObject ; // タイプが、CLOB,ROWID,TIMESTAMP かどうか。 565 566 /** 567 * 引数付コンストラクター 568 * 569 * @og.rev 6.3.3.0 (2015/07/25) STRUCTタイプの対応 570 * 571 * @param name カラム名(ResultSetMetaData#getColumnLabel(int) の toUpperCase) 572 * @param type java.sql.Types の定数定義 573 * @param size カラムサイズ(ResultSetMetaData#getColumnDisplaySize(int)) 574 * @param isWrit 書き込み許可(ResultSetMetaData#isWritable(int)) 575 * @param clmNo ResultSet での元のカラムNo( 1から始まる番号 ) 576 * @param objNo STRUCT での配列番号( 0から始まる番号 ) 577 */ 578 ColumnInfo( final String name , final int type , final int size , final boolean isWrit 579 , final int clmNo , final int objNo ) { 580 this.name = name ; 581 this.type = type ; 582 this.size = size ; 583 this.isWrit = isWrit; 584 this.clmNo = clmNo; 585 this.objNo = objNo; 586 isStruct = objNo >= 0; // Struct型かどうかは、配列番号で判定する。 587 isObject = type == Types.CLOB || type == Types.ROWID || type == Types.TIMESTAMP ; 588 } 589 590 /** 591 * カラム名を返します。 592 * 593 * @og.rev 6.3.3.0 (2015/07/25) STRUCTタイプの対応 594 * 595 * @return カラム名 596 */ 597 public String getName() { return name; } 598 } 599}