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.plugin.table; 017 018 import java.io.File; 019 import java.io.PrintWriter; 020 import java.util.Map; 021 022 import org.opengion.fukurou.db.DBUtil; 023 import org.opengion.fukurou.db.Transaction; // 5.5.2.6 (2012/05/25) 024 import org.opengion.fukurou.util.ErrorMessage; 025 import org.opengion.fukurou.util.FileUtil; 026 import org.opengion.fukurou.util.FixLengthData; 027 import org.opengion.fukurou.util.StringUtil; 028 import org.opengion.hayabusa.common.HybsSystem; 029 import org.opengion.hayabusa.common.HybsSystemException; 030 import org.opengion.hayabusa.db.AbstractTableFilter; 031 import org.opengion.hayabusa.db.DBTableModel; 032 033 /** 034 * TableFilter_INDEX は、TableUpda インターフェースを継承した、DBTableModel 処?の 035 * 実?ラスです? 036 * 037 * ここでは、イン?クス?の検索結果より、GF07 のイン?クスカラ?義??ブルから 038 * ?な??を取得し、イン?クス作?スクリプトを作?します? 039 * 出力ファイルは、テーブル名?C.sql" と?命名規則で作?します? 040 * 検索では?SYSTEM_ID,TBLSYU,TABLE_NAME,TABLE_LABEL,INDEX_NAME,NAME_JA,INDTYPE,TABLESPACE_NAME,INITIAL_EXTENT,NEXT_EXTENT) 041 * の?を取得する?があります? 042 * 043 * パラメータは、tableFilterタグの keys, vals にそれぞれ記述するか?BODY 部にCSS形式で記述します? 044 * 【パラメータ? 045 * { 046 * DIR : {@BASE_DIR}/sql/02_INDEX ; 出力ファイルの基準フォル???) 047 * XML : false ; XML出力を行うかど?[true/false]を指定しま?初期値:false)? 048 * } 049 * 050 * @og.formSample 051 * ●形式? 052 * select SYSTEM_ID,TBLSYU,TABLE_NAME,TABLE_LABEL,INDEX_NAME,NAME_JA,INDTYPE,TABLESPACE_NAME,INITIAL_EXTENT,NEXT_EXTENT from GF07 053 * ?<og:tableFilter classId="INDEX" keys="DIR,XML" vals="{@BASE_DIR}/sql/02_INDEX,false" /> 054 * 055 * ② <og:tableFilter classId="INDEX" > 056 * { 057 * DIR : {@BASE_DIR}/sql/02_INDEX ; 058 * XML : false ; 059 * } 060 * </og:tableFilter> 061 * 062 * @og.rev 5.6.6.0 (2013/07/05) keys の整合?チェ?を追? 063 * 064 * @version 0.9.0 2000/10/17 065 * @author Kazuhiko Hasegawa 066 * @since JDK1.1, 067 */ 068 public class TableFilter_INDEX extends AbstractTableFilter { 069 //* こ?プログラ??VERSION??を設定します? {@value} */ 070 private static final String VERSION = "5.6.6.1 (2013/07/12)" ; 071 072 /** 073 * keys の整合?チェ?を行うための初期設定を行います? 074 * 075 * @og.rev 5.6.6.1 (2013/07/12) keys の整合?チェ?対? 076 * 077 * @param keysMap keys の整合?チェ?を行うための Map 078 */ 079 @Override 080 protected void init( final Map<String,String> keysMap ) { 081 keysMap.put( "DIR" , "出力ファイルの基準フォル???)" ); 082 keysMap.put( "XML" , "XML出力を行うかど?[true/false]を指?初期値:false)" ); 083 } 084 085 private static final String[] DBKEY = {"SYSTEM_ID","TBLSYU","TABLE_NAME","TABLE_LABEL","INDEX_NAME","NAME_JA","INDTYPE", 086 "TABLESPACE_NAME","INITIAL_EXTENT","NEXT_EXTENT" }; 087 088 // 5.1.1.0 (2009/12/01) ??タのアクセス用の配?番号のID?private ?protected にします? 089 /** ??タのアクセス用の配?番号 {@value} */ 090 protected static final int SYSTEM_ID = 0; 091 /** ??タのアクセス用の配?番号 {@value} */ 092 protected static final int TBLSYU = 1; 093 /** ??タのアクセス用の配?番号 {@value} */ 094 protected static final int TABLE_NAME = 2; 095 /** ??タのアクセス用の配?番号 {@value} */ 096 protected static final int TABLE_LABEL = 3; // GF02 の NAME_JA より JOIN 097 /** ??タのアクセス用の配?番号 {@value} */ 098 protected static final int INDEX_NAME = 4; 099 /** ??タのアクセス用の配?番号 {@value} */ 100 protected static final int INDTYPE = 6; 101 /** ??タのアクセス用の配?番号 {@value} */ 102 protected static final int TABLESPACE_NAME = 7; 103 /** ??タのアクセス用の配?番号 {@value} */ 104 protected static final int INITIAL_EXTENT = 8; 105 /** ??タのアクセス用の配?番号 {@value} */ 106 protected static final int NEXT_EXTENT = 9; 107 108 // 5.1.1.2 (2009/12/10) 109 // private static final String GF07_SEL = "select CLM" 110 // + " from GF07" 111 // + " where SYSTEM_ID=? and TBLSYU=? and TABLE_NAME=? and INDEX_NAME=?" 112 // + " and FGJ='1'" 113 // + " order by SEQNO" ; 114 private static final String GF07_SEL = "select A.CLM, B.USE_LENGTH" 115 + " from GF07 A left outer join GF05 B" 116 + " on A.SYSTEM_ID = B.SYSTEM_ID" 117 + " and A.TBLSYU = B.TBLSYU" 118 + " and A.TABLE_NAME = B.TABLE_NAME" 119 + " and A.CLM = B.CLM" 120 + " and B.FGJ = '1'" 121 + " where A.SYSTEM_ID=? and A.TBLSYU=? and A.TABLE_NAME=? and A.INDEX_NAME=?" 122 + " and A.FGJ='1'" 123 + " order by A.SEQNO" ; 124 125 // private static final String ENCODE = "Windows-31J" ; 126 private static final String ENCODE = "UTF-8" ; // 4.3.6.6 (2009/05/15) 127 // private static final String CR = HybsSystem.CR ; // 5.1.1.0 (2009/12/01) CR 定義をAbstractTableFilterで行う? 128 129 private static final String CMNT = "************************************************************************" ; 130 131 private static final int X = FixLengthData.X ; 132 private static final int S = FixLengthData.S ; 133 private static final int K = FixLengthData.K ; 134 135 /** ?定数 */ 136 protected static final String XML_START_TAG = "<?xml version='1.0' encoding='UTF-8'?>" + CR + "<ROWSET tableName='xxx'>"; 137 protected static final String XML_END_TAG = "</ROWSET>"; 138 protected static final String EXEC_START_TAG= "<EXEC_SQL>"; 139 protected static final String EXEC_END_TAG = "</EXEC_SQL>"; 140 141 /** XML形式かど? */ 142 protected boolean isXml = false; // 4.3.7.0 (2009/06/01) 143 144 /** 145 * DBTableModel処?実行します? 146 * 147 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得?為,ApplicationInfoオブジェクトを設? 148 * @og.rev 4.0.0.0 (2007/11/28) メソ?の戻り?をチェ?します? 149 * @og.rev 4.3.7.0 (2009/06/01) XML出力機?追? 150 * @og.rev 5.1.1.0 (2009/12/01) XML_START_TAG に、tableName をセ?します? 151 * @og.rev 5.1.9.0 (2010/08/01) Transaction 対? 152 * @og.rev 5.5.2.6 (2012/05/25) protected変数を?private化したため?getterメソ?で取得するよ?変更 153 * 154 * @return 実行結果の??ブルモ? 155 */ 156 public DBTableModel execute() { 157 DBTableModel table = getDBTableModel(); // 5.5.2.6 (2012/05/25) インターフェースにgetterメソ?追? 158 159 isXml = StringUtil.nval( getValue( "XML" ), false ); 160 161 int[] clmNo = getTableColumnNo( DBKEY ); 162 int rowCnt = table.getRowCount(); 163 164 File dir = new File( getValue( "DIR" ) ); 165 if( ! dir.exists() && ! dir.mkdirs() ) { 166 String errMsg = "??フォル?作?できませんでした?" + dir + "]" ; 167 // 4.3.4.4 (2009/01/01) 168 throw new HybsSystemException( errMsg ); 169 } 170 171 String[] data = null; 172 String bkTableName = null; 173 PrintWriter writer = null; 174 Transaction tran = getTransaction(); // 5.5.2.6 (2012/05/25) 175 for( int row=0; row<rowCnt; row++ ) { 176 String tableName = null; 177 // String tableLbl = null; 178 String indexName = null; 179 try { 180 data = table.getValues( row ); 181 String systemId = data[clmNo[SYSTEM_ID]]; 182 String tblsyu = data[clmNo[TBLSYU]]; 183 tableName = data[clmNo[TABLE_NAME]]; 184 // tableLbl = data[clmNo[TABLE_LABEL]]; 185 indexName = data[clmNo[INDEX_NAME]]; 186 187 // ??ブルがキーブレイクすると、セーブファイルを?り替える? 188 if( ! tableName.equals( bkTableName ) ) { 189 if( writer != null ) { 190 if( isXml ) { writer.println( XML_END_TAG ); } 191 writer.close(); 192 } 193 bkTableName = tableName; 194 writer = FileUtil.getPrintWriter( new File( dir,tableName + ( isXml ? "C.xml" : "C.sql" ) ),ENCODE ); 195 if( isXml ) { writer.println( XML_START_TAG.replace( "xxx",tableName ) ); } // 5.1.1.0 (2009/12/01) tableName をセ? 196 writer.print( makeHeadLine( clmNo,data ) ); 197 } 198 199 String[] vals = new String[] { systemId,tblsyu,tableName,indexName }; 200 // String[][] gf07 = DBUtil.dbExecute( GF07_SEL,vals,appInfo ); 201 String[][] gf07 = DBUtil.dbExecute( GF07_SEL,vals,tran ); // 5.1.9.0 (2010/08/01) Transaction 対? 202 if( gf07.length == 0 ) { 203 System.out.println( "TABLE=[" + tableName + "],INDEX=[" + indexName + "] is Not Found!" ); 204 continue; 205 } 206 // ??ブルに対するカラ?? 207 StringBuilder buf = new StringBuilder() ; 208 for( int j=0; j<gf07.length; j++ ) { 209 // 5.1.1.2 (2009/12/10) 210 // buf.append( gf07[j][0] ).append( "," ); 211 buf.append( makeIndexClmStr( gf07[j][0], gf07[j][1] ) ).append( "," ); 212 } 213 buf.deleteCharAt( buf.length()-1 ); // ?? "," を取り除く?? 214 215 String clms = buf.toString(); 216 217 writer.print( makeLineList( clmNo,data,clms ) ); 218 writer.println( makeEndLine( clmNo,data ) ); 219 } 220 catch( RuntimeException ex ) { 221 ErrorMessage errMessage = makeErrorMessage( "TableFilter_INDEX Error",ErrorMessage.NG ); 222 errMessage.addMessage( row+1,ErrorMessage.NG,"INDEX",ex.getMessage() ); 223 errMessage.addMessage( row+1,ErrorMessage.NG,"INDEX",StringUtil.array2csv( data ) ); 224 errMessage.addMessage( row+1,ErrorMessage.NG,"INDEX","TABLE=[" + tableName + "],INDEX=[" + indexName + "]" ); 225 // BAT から呼び出す?合があるため、標準エラー出力にも情報を?しておきます? 226 System.out.println( errMessage ); 227 } 228 } 229 if( isXml ) { writer.println( XML_END_TAG ); } 230 if( writer != null ) { writer.close(); } 231 232 return table; 233 } 234 235 /** 236 * ヘッ??部??処?実行します? 237 * 238 * @og.rev 5.6.6.0 (2013/07/05) FixLengthData の簡易コンストラクタを使用 239 * 240 * @param clmNo カラ?号配? 241 * @param data ?行?の??タ配? 242 * 243 * @return ヘッ??部???? 244 */ 245 protected String makeHeadLine( final int[] clmNo,final String[] data ) { 246 // String LINE1 = data[clmNo[TABLE_NAME]] ; 247 String tableName = data[clmNo[TABLE_NAME]]; 248 String LINE1 = tableName + " ( " + data[clmNo[TABLE_LABEL]] + " )" ; 249 String LINE2 = "Created : " + HybsSystem.getDate() ; 250 251 // 5.6.6.0 (2013/07/05) FixLengthData の簡易コンストラクタを使用 252 // FixLengthData fixData = new FixLengthData(3); 253 254 int[] addLen = new int[] { 0,0,0 }; // ?ータ間?スペ?ス 255 int[] type = new int[] { X,K,X }; // ?ータの種別 X:半?S:空白前埋?K:全角混在 256 // fixData.setAddLength( addLen ); 257 // fixData.setType( type ); 258 FixLengthData fixData = new FixLengthData( addLen,type ); 259 260 String[][] outData = new String[][] { 261 { "/**", CMNT , "**/" }, 262 { "/* ", LINE1, " */" }, 263 { "/* ", LINE2, " */" }, 264 { "/**", CMNT , "**/" }, 265 }; 266 267 fixData.addAllListData( outData ); 268 269 return fixData.getAllFixData(); 270 271 // for( int i=0; i<outData.length; i++ ) { 272 // fixData.addListData( outData[i] ); 273 // } 274 275 // StringBuilder buf = new StringBuilder(); 276 // for( int i=0; i<outData.length; i++ ) { 277 // buf.append( fixData.getFixData( i ) ).append( CR ); 278 // } 279 280 // return buf.toString(); 281 } 282 283 /** 284 * イン?クス作?の処?実行します? 285 * 286 * @og.rev 5.3.8.0 (2011/08/01) プライマリキー対? 287 * 288 * @param clmNo カラ?号配? 289 * @param data ?行?の??タ配? 290 * @param clms カラ?(CSV形? 291 * 292 * @return 作?された1行?の?? 293 */ 294 protected String makeLineList( final int[] clmNo,final String[] data,final String clms ) { 295 String tableName = data[clmNo[TABLE_NAME]]; 296 String indexName = data[clmNo[INDEX_NAME]]; 297 String idxtype = data[clmNo[INDTYPE]]; 298 299 StringBuilder buf = new StringBuilder(); 300 301 buf.append( CR ); // 先?に、改行を入れておきます? 302 if( isXml ) { buf.append( EXEC_START_TAG ).append( CR ); } 303 304 // 5.3.8.0 (2011/08/01) プライマリキー対? 305 if( "0".equals( idxtype ) ) { // プライマリキー 306 buf.append( "ALTER TABLE " ).append( tableName ).append( " ADD CONSTRAINT " ); 307 buf.append( indexName ).append( " PRIMARY KEY ( " ).append( clms ); 308 buf.append( " )" ); 309 } 310 else if( "1".equals( idxtype ) ) { // ユニ?クキー 311 buf.append( "ALTER TABLE " ).append( tableName ).append( " ADD CONSTRAINT " ); 312 buf.append( indexName ).append( " UNIQUE( " ).append( clms ); 313 buf.append( " )" ); 314 } 315 else { 316 buf.append( "CREATE INDEX " ).append( indexName ).append( " ON " ); 317 buf.append( tableName ).append( "( " ).append( clms ); 318 buf.append( " )" ); 319 } 320 321 return buf.toString(); 322 } 323 324 /** 325 * 定義の??部??処?実行します? 326 * 327 * @og.rev 5.3.9.0 (2011/09/01) プライマリキー対応? 328 * 329 * @param clmNo カラ?号配? 330 * @param data ?行?の??タ配? 331 * 332 * @return 定義の??部? 333 */ 334 protected String makeEndLine( final int[] clmNo,final String[] data ) { 335 StringBuilder buf = new StringBuilder(); 336 buf.append( CR ); // 先?に、改行を入れておきます? 337 338 String idxtype = data[clmNo[INDTYPE]]; 339 // if( "1".equals( idxtype ) ) { // プライマリキー 340 if( "0".equals( idxtype ) || "1".equals( idxtype ) ) { // 0:プライマリキー , 1:ユニ?クキー 341 buf.append( "USING INDEX " ); 342 } 343 344 buf.append( "TABLESPACE " ).append( data[clmNo[TABLESPACE_NAME]] ).append( CR ); 345 buf.append( "STORAGE( INITIAL " ).append( data[clmNo[INITIAL_EXTENT]] ); 346 buf.append( "K NEXT " ).append( data[clmNo[NEXT_EXTENT]] ); 347 buf.append( "K PCTINCREASE 0 )" ); 348 349 if( isXml ) { buf.append( CR ).append( EXEC_END_TAG ); } 350 else { buf.append( ";" ); } 351 352 return buf.toString(); 353 } 354 355 /** 356 * イン?クスを作?するための??を返します? 357 * 通常、カラ?をそのまま返します? 358 * ?、唯??MySQLの場合?500バイト以上?カラ?つ?は、TEXTで定義しており? 359 * こ?場合?イン?クス化するバイト数(?255)を指定する?があります? 360 * こ?ケースに対応するため?カラ?とバイト数を?に判定し??ン?クス? 361 * 作?するための??を作?します? 362 * 363 * @param clm カラ? 364 * @param useLen カラ??バイト数 365 * 366 * @return イン?クスカラ???? 367 * @see TableFilter_INDEX_MYSQL 368 */ 369 protected String makeIndexClmStr( final String clm, final String useLen ) { 370 return clm; 371 } 372 }