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.process; 017 018 import org.opengion.fukurou.util.Argument; 019 import org.opengion.fukurou.util.SystemParameter; 020 import org.opengion.fukurou.util.LogWriter; 021 022 import org.opengion.fukurou.util.HybsEntry ; 023 import org.opengion.fukurou.util.Closer; 024 import org.opengion.fukurou.db.ConnectionFactory; 025 026 import java.util.Map ; 027 import java.util.LinkedHashMap ; 028 import java.util.Locale ; 029 030 import java.sql.Connection; 031 import java.sql.Statement; 032 import java.sql.ResultSet; 033 import java.sql.ResultSetMetaData; 034 import java.sql.SQLException; 035 036 /** 037 * Process_DBReaderは、データベ?スから読み取った?容を?LineModel に設定後? 038 * 下流に渡す?FirstProcess インターフェースの実?ラスです? 039 * 040 * ??タベ?スから読み取った?容より、LineModelを作?し?下?プロセス 041 * チェインは、チェインして?ため、データは上流から下流へと渡されます?) 042 * に渡します?ここで?できるのは、検索系SQL のみです? 043 * 044 * ??タベ?ス接続?等?、ParamProcess のサブクラス(Process_DBParam)に 045 * 設定された接?Connection)を使用します? 046 * 047 * 引数??中にスペ?スを含??合?、ダブルコー??ション("") で括って下さ?? 048 * 引数??の ?』?前後には、スペ?スは挟めません。??key=value の様に 049 * 繋げてください? 050 * 051 * SQL?は、{@DATE.YMDH}等?シス?変数が使用できます? 052 * 053 * @og.formSample 054 * Process_DBReader -dbid=DBGE -sql="select * from GEA08" 055 * 056 * [ -dbid=DB接続ID ] ??-dbid=DBGE (? Process_DBParam の -configFile で?す?DBConfig.xml ファイルで規? 057 * [ -sql=検索SQL? ] ??-sql="select * from GEA08" 058 * [ -sqlFile=検索SQLファイル ] ??-sqlFile=select.sql 059 * -sql= を指定しな??合?、ファイルで??してください? 060 * [ -sql_XXXX=固定? ] ??-sql_SYSTEM_ID=GE 061 * SQL?の{@XXXX}??を指定?固定?で置き換えます? 062 * WHERE SYSTEM_ID='{@SYSTEM_ID}' ?WHERE SYSTEM_ID='GE' 063 * [ -fetchSize=100 ] ?フェ?する行数(初期値:100) 064 * [ -display=false|true ] ?結果を標準?力に表示する(true)かしな?false)?初期値:false[表示しない]) 065 * 066 * @version 4.0 067 * @author Kazuhiko Hasegawa 068 * @since JDK5.0, 069 */ 070 public class Process_DBReader extends AbstractProcess implements FirstProcess { 071 private static final String SQL_KEY = "sql_" ; 072 073 private Connection connection = null; 074 private Statement stmt = null ; 075 private ResultSet resultSet = null; 076 private LineModel newData = null; 077 private int count = 0; 078 private int fetchSize = 100; 079 080 private String dbid = null; 081 private boolean display = false; // 表示しな? 082 083 private static final Map<String,String> mustProparty ; // ?プロパティ???チェ?用 Map 084 private static final Map<String,String> usableProparty ; // ?プロパティ?整合?チェ? Map 085 086 static { 087 mustProparty = new LinkedHashMap<String,String>(); 088 089 usableProparty = new LinkedHashMap<String,String>(); 090 usableProparty.put( "dbid", "Process_DBParam の -configFile で?す?DBConfig.xml ファイルで規? ); 091 usableProparty.put( "sql", "検索SQL?sql or sqlFile ??)? \"select * from GEA08\"" ); 092 usableProparty.put( "sqlFile", "検索SQLファイル(sql or sqlFile ??)? select.sql" ); 093 usableProparty.put( "sql_", "SQL?の{@XXXX}??を指定?固定?で置き換えます?" + 094 CR + "WHERE SYSTEM_ID='{@SYSTEM_ID}' ?WHERE SYSTEM_ID='GE'" ); 095 usableProparty.put( "fetchSize","フェ?する行数 (初期値:100)" ); 096 usableProparty.put( "display", "結果を標準?力に表示する(true)かしな?false)? + 097 CR + "(初期値:false:表示しな?" ); 098 } 099 100 /** 101 * ?ォルトコンストラクター? 102 * こ?クラスは、動??されます??ォルトコンストラクターで? 103 * super クラスに対して、?な初期化を行っておきます? 104 * 105 */ 106 public Process_DBReader() { 107 super( "org.opengion.fukurou.process.Process_DBReader",mustProparty,usableProparty ); 108 } 109 110 /** 111 * プロセスの初期化を行います?初めに??、呼び出されます? 112 * 初期処?ファイルオープン??オープン?に使用します? 113 * 114 * @og.rev 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します? 115 * 116 * @param paramProcess ??タベ?スの接続???などを持って?オブジェク? 117 */ 118 public void init( final ParamProcess paramProcess ) { 119 Argument arg = getArgument(); 120 121 String sql =arg.getFileProparty("sql","sqlFile",true); 122 String fSize =arg.getProparty("fetchSize"); 123 display =arg.getProparty("display",display); 124 125 dbid = arg.getProparty("dbid"); 126 connection = paramProcess.getConnection( dbid ); 127 128 // 3.8.0.1 (2005/06/17) SQL?? {@XXXX} ??の固定?への置き換? 129 HybsEntry[] entry =arg.getEntrys(SQL_KEY); //配? 130 SystemParameter sysParam = new SystemParameter( sql ); 131 sql = sysParam.replace( entry ); 132 133 // SQL?? {@XXXX} ??の固定?への置き換? 134 if( fSize != null ) { fetchSize = Integer.parseInt( fSize ); } 135 136 try { 137 stmt = connection.createStatement(); 138 if( fetchSize > 0 ) { stmt.setFetchSize( fetchSize ); } 139 resultSet = stmt.executeQuery( sql ); 140 141 newData = createLineModel( resultSet ); 142 143 if( display ) { println( newData.nameLine() ); } 144 } 145 catch (SQLException ex) { 146 // 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します? 147 String errMsg = "Query の実行に問題があります?" + CR 148 + "errMsg=[" + ex.getMessage() + "]" + CR 149 + "errCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR 150 + "dbid=[" + dbid + "]" + CR 151 + "sql =[" + sql + "]" ; 152 // String errMsg = "Query の実行に問題があります?[" + sql + "]" ; 153 throw new RuntimeException( errMsg,ex ); 154 } 155 } 156 157 /** 158 * プロセスの終?行います??に??、呼び出されます? 159 * 終???ファイルクローズ??クローズ?に使用します? 160 * 161 * @og.rev 4.0.0.0 (2007/11/27) commit,rollback,remove 処?追? 162 * 163 * @param isOK ト?タルで、OK?たかど?[true:成功/false:失敗] 164 */ 165 public void end( final boolean isOK ) { 166 boolean flag1 = Closer.resultClose( resultSet ); 167 resultSet = null; 168 boolean flag2 = Closer.stmtClose( stmt ); 169 stmt = null; 170 171 ConnectionFactory.remove( connection,dbid ); 172 173 if( !flag1 || !flag2 ) { 174 String errMsg = "ス??トメントをクローズ出来ません?; 175 throw new RuntimeException( errMsg ); 176 } 177 } 178 179 /** 180 * こ???タの処?おいて、次の処?出来るかど?を問?わせます? 181 * こ?呼び出し1回毎に、次の??タを取得する準備を行います? 182 * 183 * @og.rev 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します? 184 * 185 * @return 処?きる:true / 処?きな?false 186 */ 187 public boolean next() { 188 try { 189 return resultSet.next() ; 190 } 191 catch (SQLException ex) { 192 String errMsg = "ネクストすることが?来ません? 193 + "errMsg=[" + ex.getMessage() + "]" + CR 194 + "errCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR ; 195 // String errMsg = "ネクストすることが?来ません?; 196 throw new RuntimeException( errMsg,ex ); 197 } 198 } 199 200 /** 201 * ??に?行データである LineModel を作?しま? 202 * FirstProcess は、次?処?チェインして???の行データ? 203 * 作?して、後続? ChainProcess クラスに処?ータを渡します? 204 * 205 * @og.rev 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します? 206 * 207 * @param rowNo 処?の行番号 208 * 209 * @return 処?換後?LineModel 210 */ 211 public LineModel makeLineModel( final int rowNo ) { 212 count++ ; 213 try { 214 for(int clm = 0; clm < newData.size(); clm++) { 215 Object obj = resultSet.getObject(clm+1); 216 if( obj == null ) { 217 // newData.setValue( clm, "" ); 218 newData.setValue( clm, null ); 219 } 220 else { 221 newData.setValue( clm, obj ); 222 } 223 } 224 newData.setRowNo( rowNo ); 225 if( display ) { println( newData.dataLine() ); } 226 } 227 catch (SQLException ex) { 228 // 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します? 229 String errMsg = "??タを??きませんでした?" + rowNo + "]件目 " + CR 230 + "errMsg=[" + ex.getMessage() + "]" + CR 231 + "errCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR 232 + "dbid=[" + dbid + "]" + CR 233 + "data=[" + newData.dataLine() + "]" + CR ; 234 // String errMsg = "??タを??きませんでした?" + rowNo + "]件目 " 235 // + newData.toString() ; 236 throw new RuntimeException( errMsg,ex ); 237 } 238 return newData; 239 } 240 241 /** 242 * ?で使用する LineModel を作?します? 243 * こ?クラスは、?ロセスチェインの基点となります?で、新?LineModel を返します? 244 * Exception 以外では、? LineModel オブジェクトを返します? 245 * 246 * @og.rev 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します? 247 * 248 * @param rs ??タベ?スカーソル(リザルトセ?) 249 * 250 * @return ??タベ?スから取り出して変換した LineModel 251 * @throws RuntimeException カラ?を取得できなかった?合? 252 */ 253 private LineModel createLineModel( final ResultSet rs ) { 254 LineModel model = new LineModel(); 255 256 try { 257 ResultSetMetaData metaData = rs.getMetaData(); 258 259 int size = metaData.getColumnCount(); 260 model.init( size ); 261 262 for(int clm = 0; clm < size; clm++) { 263 String name = (metaData.getColumnLabel(clm+1)).toUpperCase(Locale.JAPAN) ; 264 model.setName( clm,name ); 265 } 266 } 267 catch (SQLException ex) { 268 // 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します? 269 String errMsg = "ResultSetMetaData から、カラ?を取得できませんでした? + CR 270 + "errMsg=[" + ex.getMessage() + "]" + CR 271 + "errCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR 272 + "dbid=[" + dbid + "]" + CR ; 273 // String errMsg = "ResultSetMetaData から、カラ?を取得できませんでした?; 274 throw new RuntimeException( errMsg,ex ); 275 } 276 return model; 277 } 278 279 /** 280 * プロセスの処?果のレポ?ト表現を返します? 281 * 処??ログラ?、?力件数、?力件数などの??です? 282 * こ???をそのまま、標準?力に出すことで、結果レポ?トと出来るよ? 283 * 形式で出してください? 284 * 285 * @return 処?果のレポ?? 286 */ 287 public String report() { 288 String report = "[" + getClass().getName() + "]" + CR 289 + TAB + "DBID : " + dbid + CR 290 + TAB + "Input Count : " + count ; 291 292 return report ; 293 } 294 295 /** 296 * こ?クラスの使用方法を返します? 297 * 298 * @return こ?クラスの使用方? 299 */ 300 public String usage() { 301 StringBuilder buf = new StringBuilder(); 302 303 buf.append( "Process_DBReaderは、データベ?スから読み取った?容を?LineModel に設定後?" ).append( CR ); 304 buf.append( "下流に渡す?FirstProcess インターフェースの実?ラスです?" ).append( CR ); 305 buf.append( CR ); 306 buf.append( "??タベ?スから読み取った?容より、LineModelを作?し?下?プロセス" ).append( CR ); 307 buf.append( "チェインは、チェインして?ため、データは上流から下流へと渡されます?)" ).append( CR ); 308 buf.append( "に渡します?ここで?できるのは、検索系SQL のみです?" ).append( CR ); 309 buf.append( CR ); 310 buf.append( "??タベ?ス接続?等?、ParamProcess のサブクラス(Process_DBParam)に" ).append( CR ); 311 buf.append( "設定された接?Connection)を使用します?" ).append( CR ); 312 buf.append( CR ); 313 buf.append( "引数??中に空白を含??合?、ダブルコー??ション(\"\") で括って下さ??" ).append( CR ); 314 buf.append( "引数??の ?』?前後には、空白は挟めません。??key=value の様に" ).append( CR ); 315 buf.append( "繋げてください? ).append( CR ); 316 buf.append( CR ); 317 buf.append( "SQL?は、{@DATE.YMDH}等?シス?変数が使用できます?" ).append( CR ); 318 buf.append( CR ).append( CR ); 319 320 buf.append( getArgument().usage() ).append( CR ); 321 322 return buf.toString(); 323 } 324 325 /** 326 * こ?クラスは、main メソ?から実行できません? 327 * 328 * @param args コマンド引数配? 329 */ 330 public static void main( final String[] args ) { 331 LogWriter.log( new Process_DBReader().usage() ); 332 } 333 }