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    }