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.StringUtil;
021 import org.opengion.fukurou.util.LogWriter;
022 import org.opengion.fukurou.util.HybsEntry ;
023 import org.opengion.fukurou.util.Closer;
024 import org.opengion.fukurou.model.Formatter;
025 import org.opengion.fukurou.db.ConnectionFactory;
026
027 import java.util.Map ;
028 import java.util.LinkedHashMap ;
029 import java.util.Set ;
030 import java.util.HashSet ;
031
032 import java.sql.Connection;
033 import java.sql.Statement;
034 import java.sql.PreparedStatement;
035 import java.sql.ParameterMetaData;
036 import java.sql.SQLException;
037
038 /**
039 * Process_DBWriter は、上流から受け取ったデータをデータベ?スに書き込?
040 * CainProcess インターフェースの実?ラスです?
041 *
042 * 上?プロセスチェインの??タは上流から下流へと渡されます?)から受け取っ?
043 * LineModel を?に、データベ?スへの書き込みを行います?
044 *
045 * ??タベ?ス接続?等?、ParamProcess のサブクラス(Process_DBParam)に
046 * 設定された接?Connection)を使用します?
047 *
048 * 引数??中にスペ?スを含??合?、ダブルコー??ション("") で括って下さ??
049 * 引数??の ?』?前後には、スペ?スは挟めません。??key=value の様に
050 * 繋げてください?
051 *
052 * SQL?は、{@DATE.YMDH}等?シス?変数が使用できます?
053 *
054 * @og.formSample
055 * Process_DBWriter -dbid=DBGE -table=GE41
056 *
057 * [ -dbid=DB接続ID ] ??-dbid=DBGE (? Process_DBParam の -configFile で?す?DBConfig.xml ファイルで規?
058 * [ -table=登録??ブルID ] ???????する?合?不要?INSERT する場合???ブルID
059 * [ -sql=検索SQL? ] ??-sql="UPDATE GE41 SET NAME_JA = [NAME_JA],LABEL_NAME = [LABEL_NAME]
060 * WHERE SYSTEM_ID = [SYSTEM_ID] AND CLM = [CLM]"
061 * [ -sqlFile=登録SQL?ァ??? ] ??-sqlFile=update.sql
062 * ?? -sql ?-sqlFile が指定されな??合??table で????ブルに全カラ?insert です?
063 * [ -sql_XXXX=固定? ] ??-sql_SYSTEM_ID=GE
064 * SQL?の{@XXXX}??を指定?固定?で置き換えます?
065 * WHERE SYSTEM_ID='{@SYSTEM_ID}' ?WHERE SYSTEM_ID='GE'
066 * [ -const_XXXX=固定? ] ??-const_FGJ=1
067 * LineModel のキー(const_ に続く??)の値に、固定?を設定します?
068 * キーが異なれ?、?のカラ?を指定できます?
069 * [ -omitClms=AAA,BBB,… ] ??-omitClms=UNIQ,FGJ,DYSET
070 * -table 属?でINSERT?自動作?する場合?取り除くカラ??
071 * カンマ区?で??できます?
072 * [ -initSql=開始時SQL? ] ??-initSql="DELETE FROM GE41 WHERE FGJ = '9'"
073 * [ -initSqlFile=開始時SQL?ァ??] ??-initSqlFile=update.sql
074 * [ -endSql=終?SQL? ] ??-endSql="UPDATE GE41 SET FGJ = '1'"
075 * [ -endSqlFile=終?SQL?ァ???] ??-endSqlFile=update.sql
076 * [ -commitCnt=commit処??] ???数毎にコミットを発行します?0 の場合?、終?でコミットしません?
077 * [ -display=[false/true] ] ??結果を標準?力に表示する(true)かしな?false)?初期値:false[表示しない])
078 * [ -debug=[false/true] ] ?デバッグ??を標準?力に表示する(true)かしな?false)?初期値:false[表示しない])
079 *
080 * @version 4.0
081 * @author Kazuhiko Hasegawa
082 * @since JDK5.0,
083 */
084 public class Process_DBWriter extends AbstractProcess implements ChainProcess {
085 private static final String CNST_KEY = "const_" ;
086 private static final String SQL_KEY = "sql_" ;
087
088 private Connection connection = null;
089 private PreparedStatement pstmt = null;
090 private ParameterMetaData pMeta = null; // 5.1.1.0 (2009/11/11) setObject に、Type を渡す?(PostgreSQL対?
091 private boolean useParamMetaData = false; // 5.1.1.0 (2009/11/11) setObject に、Type を渡す?(PostgreSQL対?
092
093 private String dbid = null;
094 private String sql = null;
095 private String initSql = null; // 5.7.2.2 (2014/01/24) 追?
096 private String endSql = null; // 5.7.2.2 (2014/01/24) 追?
097 private String table = null;
098 private int[] clmNos = null; // ファイルのヘッ??のカラ?号
099 private int commitCnt = 0; // コミットするまとめ件数
100 private boolean display = false; // 表示しな?
101 private boolean debug = false; // 5.7.3.0 (2014/02/07) ????
102
103 private String[] cnstClm = null; // 固定?を設定するカラ?
104 private int[] cnstClmNos = null; // 固定?を設定するカラ?号
105 private String[] constVal = null; // カラ?号に対応した固定?
106
107 private boolean firstRow = true; // ??の?目
108 private int count = 0;
109 private String[] omitClms = null; // 4.0.0.0 (2007/09/21) table ?時に取り除くカラ?
110
111 private static final Map<String,String> mustProparty ; // ?プロパティ???チェ?用 Map
112 private static final Map<String,String> usableProparty ; // ?プロパティ?整合?チェ? Map
113
114 static {
115 mustProparty = new LinkedHashMap<String,String>();
116
117 usableProparty = new LinkedHashMap<String,String>();
118 usableProparty.put( "dbid", "Process_DBParam の -configFile で?す?DBConfig.xml ファイルで規? );
119 usableProparty.put( "table", "INSERT する場合???ブルID SQL??する?合?不要?" );
120 usableProparty.put( "sql", "更新SQL?sql or sqlFile ??)" +
121 CR + "? \"UPDATE GE41 " +
122 CR + "SET NAME_JA = [NAME_JA],LABEL_NAME = [LABEL_NAME] " +
123 CR + "WHERE SYSTEM_ID = [SYSTEM_ID] AND CLM = [CLM]\"" );
124 usableProparty.put( "sqlFile", "登録SQLファイル(sql or sqlFile ??)? update.sql" );
125 usableProparty.put( "sql_", "SQL?の{@XXXX}??を指定?固定?で置き換えます?" +
126 CR + "WHERE SYSTEM_ID='{@SYSTEM_ID}' ?WHERE SYSTEM_ID='GE'" );
127 usableProparty.put( "const_", "LineModel のキー(const_ に続く??)の値に、固定?? +
128 CR + "設定します?キーが異なれ?、?のカラ?を指定できます?" +
129 CR + "? -sql_SYSTEM_ID=GE" );
130 // 4.0.0.0 (2007/09/21) 属?を追?
131 usableProparty.put( "omitClms", "-table 属?でINSERT?自動作?する場合?取り除くカラ?? +
132 CR + "カンマ区?で??できます?" +
133 CR + "? -omitClms=UNIQ,FGJ,DYSET" );
134 usableProparty.put( "initSql" , "開始時に??実行されるSQL??します?" ); // 5.7.2.2 (2014/01/24) 追?
135 usableProparty.put( "initSqlFile", "開始時に??実行されるSQLファイルを指定します?" ); // 5.7.2.2 (2014/01/24) 追?
136 usableProparty.put( "endSql" , "終?に??実行されるSQL??します?" ); // 5.7.2.2 (2014/01/24) 追?
137 usableProparty.put( "endSqlFile" , "終?に??実行されるSQLファイルを指定します?" ); // 5.7.2.2 (2014/01/24) 追?
138 usableProparty.put( "commitCnt", "?数毎にコミットを発行します?" +
139 CR + "0 の場合?、終?でコミットしません(初期値:0)" );
140 usableProparty.put( "display", "結果を標準?力に表示する(true)かしな?false)? +
141 CR + "(初期値:false:表示しな?" );
142 usableProparty.put( "debug", "????を標準?力に表示する(true)かしな?false)? +
143 CR + "(初期値:false:表示しな?" ); // 5.7.3.0 (2014/02/07) ????
144 }
145
146 /**
147 * ?ォルトコンストラクター?
148 * こ?クラスは、動??されます??ォルトコンストラクターで?
149 * super クラスに対して、?な初期化を行っておきます?
150 *
151 */
152 public Process_DBWriter() {
153 super( "org.opengion.fukurou.process.Process_DBWriter",mustProparty,usableProparty );
154 }
155
156 /**
157 * プロセスの初期化を行います?初めに??、呼び出されます?
158 * 初期処?ファイルオープン??オープン?に使用します?
159 *
160 * @og.rev 4.0.0.0 (2007/09/21) omitClms 属?を追?
161 * @og.rev 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す?(PostgreSQL対?
162 * @og.rev 5.3.8.0 (2011/08/01) useParamMetaData ?ConnectionFactory経由で取得?(PostgreSQL対?
163 * @og.rev 5.7.2.2 (2014/01/24) initSql,initSqlFile,endSql,endSqlFile 追?
164 *
165 * @param paramProcess ??タベ?スの接続???などを持って?オブジェク?
166 */
167 public void init( final ParamProcess paramProcess ) {
168 Argument arg = getArgument();
169
170 table = arg.getProparty("table");
171 sql = arg.getFileProparty("sql","sqlFile",false);
172 initSql = arg.getFileProparty("initSql","initSqlFile",false); // 5.7.2.2 (2014/01/24) 追?
173 endSql = arg.getFileProparty("endSql","endSqlFile",false); // 5.7.2.2 (2014/01/24) 追?
174 commitCnt = arg.getProparty("commitCnt",commitCnt);
175 display = arg.getProparty("display",display);
176 debug = arg.getProparty("debug",debug); // 5.7.3.0 (2014/02/07) ????
177 // if( debug ) { println( arg.toString() ); } // 5.7.3.0 (2014/02/07) ????
178
179 dbid = arg.getProparty("dbid");
180 connection = paramProcess.getConnection( dbid );
181 // 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す?(PostgreSQL対?
182 // useParamMetaData = ApplicationInfo.useParameterMetaData( connection );
183 useParamMetaData = ConnectionFactory.useParameterMetaData( dbid ); // 5.3.8.0 (2011/08/01)
184
185 // 取り除くカラ?リストを配?に変換します?
186 String tempClms = arg.getProparty("omitClms",null);
187 if( tempClms != null ) {
188 omitClms = StringUtil.csv2Array( tempClms );
189 }
190
191 if( sql == null && table == null ) {
192 String errMsg = "sql を指定しな??合?、table を??してください?;
193 throw new RuntimeException( errMsg );
194 }
195
196 // 3.8.0.1 (2005/06/17) {@DATE.XXXX} 変換処??追?
197 // {@DATE.YMDH} などの??を?yyyyMMddHHmmss 型?日付に置き換えます?
198 // SQL?? {@XXXX} ??の固定?への置き換?
199 HybsEntry[] entry =arg.getEntrys(SQL_KEY); // 配?
200 SystemParameter sysParam = new SystemParameter( sql );
201 sql = sysParam.replace( entry );
202
203 // 5.7.2.2 (2014/01/24) initSql,endSql に?@XXXX} ??の置き換えを行います?
204 if( initSql != null ) {
205 SystemParameter sysParam2 = new SystemParameter( initSql );
206 initSql = sysParam2.replace( entry );
207 execSql( initSql );
208 }
209 if( endSql != null ) {
210 SystemParameter sysParam3 = new SystemParameter( endSql );
211 endSql = sysParam3.replace( entry );
212 }
213
214 HybsEntry[] cnstKey = arg.getEntrys( CNST_KEY ); // 配?
215 int csize = cnstKey.length;
216 cnstClm = new String[csize];
217 constVal = new String[csize];
218 for( int i=0; i<csize; i++ ) {
219 cnstClm[i] = cnstKey[i].getKey();
220 constVal[i] = cnstKey[i].getValue();
221 }
222 }
223
224 /**
225 * プロセスの終?行います??に??、呼び出されます?
226 * 終???ファイルクローズ??クローズ?に使用します?
227 *
228 * @og.rev 4.0.0.0 (2007/11/27) commit,rollback,remove 処?追?
229 * @og.rev 5.1.1.0 (2009/11/11) pMeta のクリア
230 * @og.rev 5.7.2.2 (2014/01/24) endSql 処??追?
231 *
232 * @param isOK ト?タルで、OK?たかど?[true:成功/false:失敗]
233 */
234 public void end( final boolean isOK ) {
235 boolean flag = Closer.stmtClose( pstmt );
236 pstmt = null;
237 pMeta = null; // 5.1.1.0 (2009/11/11)
238
239 // 5.7.2.2 (2014/01/24) endSql の実?
240 Throwable th2 = null;
241 if( isOK && endSql != null ) {
242 try { execSql( endSql ); } catch (Throwable th) { th2 = th ; }
243 }
244
245 // 5.7.2.2 (2014/01/24) すべて異常がな??合?み、??る様に変更?
246 // if( isOK ) {
247 if( isOK && flag && th2 == null ) {
248 Closer.commit( connection );
249 }
250 else {
251 Closer.rollback( connection );
252 }
253 ConnectionFactory.remove( connection,dbid );
254
255 if( !flag ) {
256 String errMsg = "ス??トメントをクローズ出来ません?;
257 throw new RuntimeException( errMsg );
258 }
259
260 // 5.7.2.2 (2014/01/24) endSql の実行失敗時の処?
261 if( th2 != null ) {
262 String errMsg = "endSql の実行に失敗しました。sql=[" + endSql + "]" + CR
263 + th2.getMessage() + CR ;
264 throw new RuntimeException( errMsg,th2 );
265 }
266 }
267
268 /**
269 * 引数の LineModel を??るメソ?です?
270 * 変換処?? LineModel を返します?
271 * 後続??行わな?????タのフィルタリングを行う場?は?
272 * null ??タを返します?つまり?null ??タは、後続??行わな?
273 * フラグの代わりにも使用して?す?
274 * なお?変換処?? LineModel と、オリジナルの LineModel が?
275 * 同?、コピ?(クローン)か?、各処?ソ??決めて?す?
276 * ドキュメントに明記されて???合?、副作用が問題になる?合??
277 * ???とに自?コピ?(クローン)して下さ??
278 *
279 * @og.rev 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す?(PostgreSQL対?
280 * @og.rev 5.3.8.0 (2011/08/01) useParamMetaData setNull 対?PostgreSQL対?
281 * @og.rev 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します?
282 *
283 * @param data オリジナルのLineModel
284 *
285 * @return 処?換後?LineModel
286 */
287 public LineModel action( final LineModel data ) {
288 count++ ;
289 // if( display ) { println( data.dataLine() ); }
290 try {
291 if( firstRow ) {
292 pstmt = makePrepareStatement( table,data );
293 // 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す?(PostgreSQL対?
294 if( useParamMetaData ) {
295 pMeta = pstmt.getParameterMetaData();
296 }
297
298 int size = cnstClm.length;
299 cnstClmNos = new int[size];
300 for( int i=0; i<size; i++ ) {
301 cnstClmNos[i] = data.getColumnNo( cnstClm[i] );
302 }
303
304 firstRow = false;
305 if( display ) { println( data.nameLine() ); } // 5.7.3.0 (2014/02/07) ????
306 }
307
308 // 固定?置き換え??
309 for( int j=0; j<cnstClmNos.length; j++ ) {
310 data.setValue( cnstClmNos[j],constVal[j] );
311 }
312
313 // 5.1.1.0 (2009/11/11) setObject に ParameterMetaData の getParameterType を渡す?(PostgreSQL対?
314 if( useParamMetaData ) {
315 for( int i=0; i<clmNos.length; i++ ) {
316 int type = pMeta.getParameterType( i+1 );
317 // 5.3.8.0 (2011/08/01) setNull 対?
318 // pstmt.setObject( i+1,data.getValue(clmNos[i]),type );
319 Object val = data.getValue(clmNos[i]);
320 if( val == null || ( val instanceof String && ((String)val).isEmpty() ) ) {
321 pstmt.setNull( i+1, type );
322 }
323 else {
324 pstmt.setObject( i+1, val, type );
325 }
326 }
327 }
328 else {
329 for( int i=0; i<clmNos.length; i++ ) {
330 pstmt.setObject( i+1,data.getValue(clmNos[i]) );
331 }
332 }
333
334 pstmt.execute();
335 if( commitCnt > 0 && ( count%commitCnt == 0 ) ) {
336 Closer.commit( connection );
337 }
338 }
339 catch (SQLException ex) {
340 // 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します?
341 String errMsg = "SQL を実行できませんでした? + CR
342 + "errMsg=[" + ex.getMessage() + "]" + CR
343 + "errCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR
344 + "dbid=[" + dbid + "]" + CR
345 + "sql =[" + sql + "]" + CR
346 + "data=[" + data.dataLine() + "]" + CR ;
347 // String errMsg = "sql=[" + sql + "]" + CR
348 // + "errorCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR ;
349 throw new RuntimeException( errMsg,ex );
350 }
351 if( display ) { println( data.dataLine() ); } // 5.1.2.0 (2010/01/01) display の条件変更
352 return data;
353 }
354
355 /**
356 * ?で使用する PreparedStatement を作?します?
357 * 引数?? SQL また?、LineModel から作?した SQL より構築します?
358 *
359 * @og.rev 4.0.0.0 (2007/09/21) omitClms 属?を追?
360 * @og.rev 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します?
361 *
362 * @param table 処?象の??ブルID
363 * @param data 処?象のLineModel
364 *
365 * @return PreparedStatementオブジェク?
366 */
367 private PreparedStatement makePrepareStatement( final String table,final LineModel data ) {
368 if( sql == null ) {
369 StringBuilder buf = new StringBuilder();
370 String[] names = data.getNames();
371
372 // カラ?取り除く??
373 if( omitClms != null ) {
374 Set<String> set = new HashSet<String>();
375 for( int i=0; i<names.length; i++ ) {
376 set.add( names[i] );
377 }
378 for( int i=0; i<omitClms.length; i++ ) {
379 set.remove( omitClms[i] );
380 }
381 names = set.toArray( new String[set.size()] );
382 }
383 int size = names.length;
384
385 buf.append( "INSERT INTO " ).append( table ).append( " (" );
386 buf.append( names[0] );
387 for( int i=1; i<size; i++ ) {
388 buf.append( "," ).append( names[i] );
389 }
390 buf.append( " ) VALUES ( ?" );
391 for( int i=1; i<size; i++ ) {
392 buf.append( ",?" );
393 }
394 buf.append( " )" );
395 sql = buf.toString();
396
397 // カラ?号を設定します?
398 clmNos = new int[size];
399 for( int i=0; i<size; i++ ) {
400 clmNos[i] = data.getColumnNo( names[i] ); // 4.0.0.0 (2007/09/21)
401 }
402 }
403 else {
404 Formatter format = new Formatter( data );
405 format.setFormat( sql );
406 sql = format.getQueryFormatString();
407 clmNos = format.getClmNos();
408 }
409
410 final PreparedStatement ps ;
411 try {
412 ps = connection.prepareStatement( sql );
413 }
414 catch (SQLException ex) {
415 // 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します?
416 String errMsg = "PreparedStatement を取得できませんでした? + CR
417 + "errMsg=[" + ex.getMessage() + "]" + CR
418 + "errCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR
419 + "dbid =[" + dbid + "]" + CR
420 + "sql =[" + sql + "]" + CR
421 + "table=[" + table + "]" + CR
422 + "data =[" + data.dataLine() + "]" + CR ;
423 // String errMsg = "PreparedStatement を取得できませんでした? + CR
424 // + "sql=[" + sql + "]" + CR
425 // + "table=[" + table + "]" + CR
426 // + "nameLine=[" + data.nameLine() + "]" ;
427 throw new RuntimeException( errMsg,ex );
428 }
429
430 return ps;
431 }
432
433 /**
434 * SQL処?実行します?
435 * 主に、initSql,endSqlの実行用です?
436 * ここでは、エラーが発生しても?connection は閉じません?
437 * ?的に、endメソ?で処?れるためです?
438 *
439 * @og.rev 5.7.2.2 (2014/01/24) 新規追?
440 *
441 * @param sql 実行するSQL?
442 */
443 private void execSql( final String sql ) {
444 Statement stmt = null;
445 try {
446 stmt = connection.createStatement();
447 stmt.execute( sql );
448 }
449 catch (SQLException ex) {
450 // 5.7.2.2 (2014/01/24) SQL実行エラーを少し詳細に出力します?
451 String errMsg = "SQL を実行できませんでした? + CR
452 + "errMsg=[" + ex.getMessage() + "]" + CR
453 + "errCode=[" + ex.getErrorCode() + "] State=[" + ex.getSQLState() + "]" + CR
454 + "dbid=[" + dbid + "]" + CR
455 + "sql =[" + sql + "]" + CR ;
456 // String errMsg = "SQL を実行できませんでした? + CR
457 // + "DBID=" + dbid + CR
458 // + "SQL =" + sql ;
459 throw new RuntimeException( errMsg,ex );
460 }
461 finally {
462 // connection は、endメソ?で処?れます?
463 Closer.stmtClose( stmt );
464 }
465 }
466
467 /**
468 * プロセスの処?果のレポ?ト表現を返します?
469 * 処??ログラ?、?力件数、?力件数などの??です?
470 * こ???をそのまま、標準?力に出すことで、結果レポ?トと出来るよ?
471 * 形式で出してください?
472 *
473 * @return 処?果のレポ??
474 */
475 public String report() {
476 String report = "[" + getClass().getName() + "]" + CR
477 + TAB + "DBID : " + dbid + CR
478 + TAB + "Output Count : " + count ;
479
480 return report ;
481 }
482
483 /**
484 * こ?クラスの使用方法を返します?
485 *
486 * @return こ?クラスの使用方?
487 */
488 public String usage() {
489 StringBuilder buf = new StringBuilder();
490
491 buf.append( "Process_DBWriter は、上流から受け取ったデータをデータベ?スに書き込? ).append( CR );
492 buf.append( "CainProcess インターフェースの実?ラスです?" ).append( CR );
493 buf.append( CR );
494 buf.append( "上?プロセスチェインの??タは上流から下流へと渡されます?)から" ).append( CR );
495 buf.append( "受け取っ?LineModel を?に、データベ?スへの書き込みを行います?" ).append( CR );
496 buf.append( CR );
497 buf.append( "??タベ?ス接続?等?、ParamProcess のサブクラス(Process_DBParam)に" ).append( CR );
498 buf.append( "設定された接?Connection)を使用します?" ).append( CR );
499 buf.append( CR );
500 buf.append( "引数??中に空白を含??合?、ダブルコー??ション(\"\") で括って下さ??" ).append( CR );
501 buf.append( "引数??の ?』?前後には、空白は挟めません。??key=value の様に" ).append( CR );
502 buf.append( "繋げてください? ).append( CR );
503 buf.append( CR );
504 buf.append( "SQL?は、{@DATE.YMDH}等?シス?変数が使用できます?" ).append( CR );
505 buf.append( CR ).append( CR );
506 buf.append( getArgument().usage() ).append( CR );
507
508 return buf.toString();
509 }
510
511 /**
512 * こ?クラスは、main メソ?から実行できません?
513 *
514 * @param args コマンド引数配?
515 */
516 public static void main( final String[] args ) {
517 LogWriter.log( new Process_DBWriter().usage() );
518 }
519 }