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?の{&#064;XXXX}??を指定?固定?で置き換えます?" +
126                                                                            CR + "WHERE SYSTEM_ID='{&#064;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    }