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 org.opengion.fukurou.db.DBUtil;
019    import org.opengion.fukurou.db.Transaction;                     // 5.5.2.6 (2012/05/25)
020    import org.opengion.fukurou.model.Formatter;
021    import org.opengion.fukurou.util.ErrorMessage;
022    import org.opengion.fukurou.util.StringUtil;
023    import org.opengion.hayabusa.db.AbstractTableFilter;
024    import org.opengion.hayabusa.db.DBTableModel;
025    
026    import java.util.Map;
027    
028    /**
029     * TableFilter_DBSELECT は、TableFilter インターフェースを継承した、DBTableModel 処?の
030     * 実?ラスです?
031     *
032     * ここでは、Body部にかかれたSQLを実行した結果を???ブルモ?にセ?します?
033     * SQL?ら取得されるカラ?と??ブルモ?のカラ?は??して??があります?
034     * 検索結果のカラ???ブルモ?に存在して???合?エラーとなります?
035     * 以下?属?を指定しな?、データが存在しな??合?NULLがセ?されます?
036     * また?2行以上検索された?合でも?1行目の??タのみをセ?します?
037     *
038     * パラメータは、tableFilterタグの keys, vals にそれぞれ記述するか?BODY 部にCSS形式で記述します?
039     * ただし?こ?フィルターは、BODY部に、SQL?記述する為、注意が?です?
040     * ルール?は、???に見つけた "{" と?}" の間???がパラメータと認識します?
041     * よって、SQL?記述する場合?、このパラメータの後ろに記述するか?keys,vals を利用ください?
042     * 【パラメータ?
043     *  {
044     *       INNER_JOIN : ??タが存在しな??合???ブルの該当行を削除します?(初期値?false)
045     *       APPEND     : 2行以上検索された?合???タをアペンドします?       (初期値?false)
046     *       SEPARATOR  : APPENDする場合?区??を?します?              (初期値?? "スペ?ス)
047     *  }
048     *
049     * Body部にかかれたSQLには[XXXX]形式?変数が指定できます?
050     *
051     * @og.formSample
052     * ●形式?
053     *      ?<og:tableFilter classId="DBSELECT" >
054     *                
055     *         </og:tableFilter>
056     *
057     *      ② <og:tableFilter classId="DBSELECT" >
058     *               {
059     *                   INNER_JOIN : true ;
060     *               }
061     *               select AAA,BBB,CCC from XXX
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   Hiroki Nakamura
068     * @since    JDK1.1,
069     */
070    public class TableFilter_DBSELECT extends AbstractTableFilter {
071            //* こ?プログラ??VERSION??を設定します?       {@value} */
072            private static final String VERSION = "5.6.6.1 (2013/07/12)" ;
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( "INNER_JOIN"       , "??タが存在しな??合???ブルの該当行を削除しま?初期値?false)"                      );
084                    keysMap.put( "APPEND"           , "2行以上検索された?合???タをアペンドしま?      (初期値?false)"                   );
085                    keysMap.put( "SEPARATOR"        , "APPENDする場合?区??を?しま?             (初期値?\" \"スペ?ス)"  );
086            }
087    
088            private DBTableModel table = null;              // 5.5.2.6 (2012/05/25) インターフェースにgetterメソ?追?
089    
090            /**
091             * DBTableModel処?実行します?
092             *
093             * @og.rev 4.3.7.0 (2009/06/01) 実??更
094             * @og.rev 5.1.9.0 (2010/08/01) Transaction 対?
095             * @og.rev 5.5.2.6 (2012/05/25) protected変数を?private化したため?getterメソ?で取得するよ?変更
096             *
097             * @return 処?果のDBTableModel
098             */
099            public DBTableModel execute() {
100                    table = getDBTableModel();              // 5.5.2.6 (2012/05/25) インターフェースにgetterメソ?追?
101    
102                    boolean innerJoin = StringUtil.nval( getValue("INNER_JOIN"), false );
103                    boolean isAppend  = StringUtil.nval( getValue("APPEND"), false );
104                    String separator  = StringUtil.nval( getValue("SEPARATOR"), " " );
105    
106                    Formatter format = new Formatter( table );
107    //              format.setFormat( sql );
108                    format.setFormat( getSql() );                           // 5.5.2.6 (2012/05/25) インターフェースにgetterメソ?追?
109                    int[] sqlClmNo = format.getClmNos();
110                    String query = format.getQueryFormatString();
111    
112                    String[] data = null;
113                    String[] param = null;
114                    int[] clmNo = null;
115                    Transaction tran = getTransaction();    // 5.5.2.6 (2012/05/25)
116                    String      dbid = getDbid();                   // 5.5.2.6 (2012/05/25)
117                    int[] rowNo = getParameterRows();               // 5.5.2.6 (2012/05/25) インターフェースにgetterメソ?追?
118                    int rowCount = rowNo.length;
119                    for ( int row = rowCount - 1; row >= 0; row-- ) {
120                            try {
121                                    param = getTableModelData( rowNo[row], sqlClmNo );
122    
123                                    final String[][] dbData;
124                                    if ( row == rowCount - 1 ) {
125    //                                              String[][] rtn = DBUtil.dbExecute( query, param, appInfo, dbid, true );
126                                            String[][] rtn = DBUtil.dbExecute( query, param, tran, dbid, true );            // 5.1.9.0 (2010/08/01) Transaction 対?
127                                            clmNo = getTableColumnNo( rtn[0] );
128                                            dbData = new String[rtn.length - 1][rtn[0].length];
129                                            System.arraycopy( rtn, 1, dbData, 0, dbData.length );
130                                    }
131                                    else {
132    //                                              dbData = DBUtil.dbExecute( query, param, appInfo, dbid, false );
133                                            dbData = DBUtil.dbExecute( query, param, tran, dbid, false );           // 5.1.9.0 (2010/08/01) Transaction 対?
134                                    }
135    
136                                    data = table.getValues( rowNo[row] );
137                                    if ( dbData != null && dbData.length > 0 && dbData[0] != null && dbData[0].length > 0 ) {
138                                            for ( int i = 0; i < clmNo.length; i++ ) {
139                                                    if( isAppend ) {
140                                                            StringBuilder buf = new StringBuilder();
141                                                            for( int j = 0; j < dbData.length; j++ ) {
142                                                                    if( j > 0 ) {
143                                                                            buf.append( separator );
144                                                                    }
145                                                                    buf.append( dbData[j][i] );
146                                                            }
147                                                            data[clmNo[i]] = buf.toString();
148                                                    }
149                                                    else {
150                                                            data[clmNo[i]] = dbData[0][i]; // 副作用を及ぼして?す?注?
151                                                    }
152                                            }
153                                    }
154                                    else if( innerJoin ) {
155                                            table.removeValue(rowNo[row]);
156                                    }
157                            }
158                            catch ( RuntimeException ex ) {
159                                    ErrorMessage errMessage = makeErrorMessage( "TableFilter_DBSELECT Error", ErrorMessage.NG );
160                                    errMessage.addMessage( rowNo[row] + 1, ErrorMessage.NG, ex.getMessage() );
161                                    errMessage.addMessage( rowNo[row] + 1, ErrorMessage.NG, StringUtil.array2csv( data ) );
162    //                              errMessage.addMessage( rowNo[row] + 1, ErrorMessage.NG, "SQL=[" + sql + "]" );
163                                    errMessage.addMessage( rowNo[row] + 1, ErrorMessage.NG, "SQL=[" + getSql() + "]" );
164                                    errMessage.addMessage( rowNo[row] + 1, ErrorMessage.NG, StringUtil.array2csv( param ) );
165                            }
166                    }
167    
168                    return table;
169            }
170    
171            /**
172             * ??行番号の、カラ?o配?(int[])に対応した?の配?を返します?
173             *
174             * 表示??タの HybsSystem.ROW_SEL_KEY を?に?ばれた 行を
175             * 処??対象とします?
176             *
177             * @param       row   行番号
178             * @param       clmNo カラ?o配?
179             *
180             * @return      行番号とカラ?o配?に対応した?値の配?
181             */
182            private String[] getTableModelData( final int row, final int[] clmNo ) {
183                    String[] values = new String[clmNo.length];
184                    for( int i = 0; i < values.length; i++ ) {
185                            values[i] = table.getValue( row, clmNo[i] );
186                    }
187                    return values;
188            }
189    }