Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.impl / src / main / java / org / gvsig / expressionevaluator / impl / function / dataaccess / SelectFunction.java @ 46517

History | View | Annotate | Download (10.3 KB)

1 44738 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2020 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.expressionevaluator.impl.function.dataaccess;
25
26
import java.util.List;
27
import org.apache.commons.lang3.Range;
28 46517 fdiaz
import org.apache.commons.lang3.StringUtils;
29 44750 jjdelcerro
import org.gvsig.expressionevaluator.Code;
30 44738 jjdelcerro
import org.gvsig.expressionevaluator.Codes;
31
import org.gvsig.expressionevaluator.ExpressionRuntimeException;
32
import org.gvsig.expressionevaluator.Interpreter;
33 44750 jjdelcerro
import org.gvsig.expressionevaluator.Optimizer;
34 44738 jjdelcerro
import org.gvsig.expressionevaluator.impl.DALFunctions;
35 44748 jjdelcerro
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT;
36 45366 omartinez
import org.gvsig.expressionevaluator.ExpressionEvaluator;
37 44738 jjdelcerro
import org.gvsig.fmap.dal.feature.Feature;
38
import org.gvsig.fmap.dal.feature.FeatureQuery;
39
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
40
import org.gvsig.fmap.dal.feature.FeatureStore;
41 45366 omartinez
import org.gvsig.fmap.dal.impl.expressionevaluator.DefaultFeatureExpressionEvaluator;
42 44752 jjdelcerro
import org.gvsig.expressionevaluator.Code.Callable;
43 46505 fdiaz
import org.gvsig.expressionevaluator.ExpressionBuilder;
44
import org.gvsig.expressionevaluator.ExpressionBuilder.Value;
45 46517 fdiaz
import org.gvsig.fmap.dal.DALLocator;
46
import org.gvsig.fmap.dal.DataManager;
47 46505 fdiaz
import org.gvsig.fmap.dal.SQLBuilder;
48 46517 fdiaz
import org.gvsig.fmap.dal.feature.FeatureType;
49 45308 fdiaz
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureQueryOrder;
50 44738 jjdelcerro
51
/**
52
 *
53
 * @author jjdelcerro
54
 */
55 45127 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
56 46088 jjdelcerro
public class SelectFunction
57
        extends AbstractSelectFunction
58
        implements Optimizer.FunctionOptimizer {
59 44738 jjdelcerro
60 46088 jjdelcerro
    public SelectFunction() {
61
        super(DALFunctions.GROUP_DATA_ACCESS,
62
                FUNCTION_SELECT,
63
                Range.is(6),
64
                "Returns a list of features of the table by applying the filter, order and limit indicated.\n"
65
                + "The syntax is:\n\n"
66
                + "SELECT * FROM table WHERE boolean_expression ORDER BY order_column LIMIT limit;\n\n"
67
                + "Indicate a filter expression with WHERE, an order or LIMIT is optional.\n"
68
                + "You can use an asterisk or enter the column names you want to retrieve separated by commas.\n"
69
                + "The SELECT statement must always end with a semicolon.",
70
                "SELECT * FROM table WHERE boolean_expression ORDER BY order_column LIMIT limit;",
71
                new String[]{
72
                    "column_names/asterisk - Names of the columns table to retrieve.",
73
                    "table_name - Name of the table",
74
                    "filter - boolean expression to apply as filter",
75
                    "order_column - the order used to retrieve the features. It is a list of column names separated by a comma. The column name can optionally be followed by ASC or DESC to indicate whether the order should be ascending or descending.",
76
                    "limit - Maximum number of features to return"
77
                },
78
                "List",
79
                true
80
        );
81
    }
82 44738 jjdelcerro
83 46088 jjdelcerro
    @Override
84
    public boolean isHidden() {
85
        return false;
86
    }
87 44738 jjdelcerro
88 46088 jjdelcerro
    @Override
89
    public boolean allowConstantFolding() {
90
        return false;
91
    }
92 44738 jjdelcerro
93 46088 jjdelcerro
    @Override
94
    public boolean useArgumentsInsteadObjects() {
95
        return true;
96 44750 jjdelcerro
    }
97 44738 jjdelcerro
98 46088 jjdelcerro
    @Override
99
    public Object call(Interpreter interpreter, Object[] args) throws Exception {
100
        throw new UnsupportedOperationException();
101 45117 jjdelcerro
    }
102 44738 jjdelcerro
103 46088 jjdelcerro
    private static final int COLUMNS = 0;
104
    private static final int TABLE = 1;
105
    private static final int WHERE = 2;
106
    private static final int ORDER = 3;
107
    private static final int ORDER_MODE = 4;
108
    private static final int LIMIT = 5;
109 44738 jjdelcerro
110 46088 jjdelcerro
    @Override
111
    public Object call(Interpreter interpreter, Codes args) throws Exception {
112
113
        String storeName = this.getTableName(args, TABLE);
114
        Code columns = getTupleOrNull(args, COLUMNS);
115
        Code where = this.getWhereCode(args, WHERE);
116
        Number limit = (Number) getObject(interpreter, args, LIMIT);
117
118
        Callable order = getTupleOrNull(args, ORDER);
119
        Callable order_mode = getTupleOrNull(args, ORDER_MODE);
120
        FeatureQueryOrder queryOrder = null;
121
        if (order != null || order_mode != null) {
122
            for (int n = 0; n < order.parameters().size(); n++) {
123
                String member = (String) interpreter.run(order.parameters().get(n));
124
                Boolean mode = (Boolean) interpreter.run(order_mode.parameters().get(n));
125
                if (queryOrder == null) {
126
                    queryOrder = new DefaultFeatureQueryOrder();
127 44750 jjdelcerro
                }
128 46088 jjdelcerro
                queryOrder.add(member, mode);
129
            }
130 45127 jjdelcerro
        }
131 46100 jjdelcerro
        FeatureStore featureStore;
132 46088 jjdelcerro
        try {
133
            featureStore = this.getFeatureStore(storeName);
134
            if (featureStore == null) {
135
                throw new ExpressionRuntimeException("Cant locate the feature store '" + storeName + "' in function '" + this.name() + "'.");
136
            }
137
            List<Feature> features;
138
            FeatureQuery query = featureStore.createFeatureQuery();
139
            if (where != null) {
140
                Code where2 = removeOuterTablesReferences(interpreter, where);
141
                ExpressionEvaluator filter = new DefaultFeatureExpressionEvaluator(where2.toString());
142
                filter.toSymbolTable().addSymbolTable(interpreter.getSymbolTable());
143
                query.addFilter(filter);
144
            }
145
            if (queryOrder != null) {
146
                query.getOrder().copyFrom(queryOrder);
147
            }
148
            if (limit != null) {
149
                query.setLimit(limit.longValue());
150
            }
151
152
            // FIXME: add columns to query.addAttributeName()
153
            query.retrievesAllAttributes();
154
            features = featureStore.getFeatures(query);
155
            return features;
156
157
        } catch (ExpressionRuntimeException ex) {
158
            throw ex;
159
        } catch (Exception ex) {
160 46100 jjdelcerro
            throw new ExpressionRuntimeException("Problems calling '" + this.name() + "' function", ex);
161 45127 jjdelcerro
        }
162 44750 jjdelcerro
    }
163
164 46088 jjdelcerro
    @Override
165
    public Code optimize(Optimizer optimizer, Callable caller) {
166
        return caller; // Don't optimize SELECT
167
    }
168 44750 jjdelcerro
169 46505 fdiaz
    @Override
170
    public ExpressionBuilder.Value toValue(ExpressionBuilder builder, Codes args) {
171
        try {
172
            SQLBuilder sqlBuilder = (SQLBuilder) builder.getProperty("SQLBUILDER");
173
            if(sqlBuilder == null){
174
                return super.toValue(builder, args);
175
            }
176
            SQLBuilder.SelectBuilder select = sqlBuilder.createSelectBuilder();
177
178
            String storeName = this.getTableName(args, TABLE);
179
            Callable columns = getTupleOrNull(args, COLUMNS);
180
            Code where = this.getWhereCode(args, WHERE);
181
            Callable order = getTupleOrNull(args, ORDER);
182
            Callable order_mode = getTupleOrNull(args, ORDER_MODE);
183
            Code limit = args.get(LIMIT);
184
185
            if (storeName != null) {
186
                select.from().table().name(storeName);
187
            }
188
189
            if (columns != null) {
190 46517 fdiaz
                if(columns.parameters().isEmpty()){
191
                    select.column().all();
192
                } else {
193
                    for (Code column : columns.parameters()) {
194
                        if (column instanceof Code.Identifier) {
195
                            String tableName = select.from().table().getName();
196
                            String columnName = ((Code.Identifier) column).name();
197
                            String builderTable = (String) builder.getProperty("Table");
198
                            FeatureType featureType = null;
199
                            if(StringUtils.equalsIgnoreCase(builderTable, tableName)){
200
                                featureType = (FeatureType) builder.getProperty("FeatureType");
201
                            } else {
202
                                DataManager dataManager = DALLocator.getDataManager();
203
                                featureType = dataManager.getStoresRepository().getFeatureType(tableName);
204
                            }
205
                            if(featureType == null){
206
                                select.column().name(
207
                                        select.from().table(),
208
                                        columnName
209
                                );
210
                            } else if(featureType.get(columnName) != null) {
211
                                select.column().name(
212
                                        select.from().table(),
213
                                        columnName
214
                                );
215
                            } else {
216
                                select.column().name(
217
                                        columnName
218
                                ).table(null);
219
                            }
220
                        }
221 46505 fdiaz
                    }
222
                }
223
            }
224
225
            if (where != null) {
226
                select.where().value(where.toValue(builder));
227
            }
228
229
            if (limit != null) {
230
                select.limit(((Number) ((Code.Constant) limit).value()).longValue());
231
            }
232
233
            if (order != null || order_mode != null) {
234
                for (int n = 0; n < order.parameters().size(); n++) {
235
                    Code member = order.parameters().get(n);
236
                    Code.Constant mode = (Code.Constant) order_mode.parameters().get(n);
237
                    select.order_by().value(member.toValue(builder)).ascending((boolean) mode.value());
238
                }
239
            }
240
            return select;
241
        } catch (Exception ex) {
242
            return super.toValue(builder, args);
243
        }
244
    }
245
246 44738 jjdelcerro
}