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