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 / SelectAggregateFunction.java @ 46954

History | View | Annotate | Download (7.96 KB)

1
/**
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 org.apache.commons.lang3.Range;
27
import org.apache.commons.lang3.StringUtils;
28
import org.gvsig.expressionevaluator.Code;
29
import org.gvsig.expressionevaluator.Codes;
30
import org.gvsig.expressionevaluator.ExpressionBuilder;
31
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_COUNT;
32
import org.gvsig.expressionevaluator.ExpressionEvaluator;
33
import org.gvsig.expressionevaluator.ExpressionRuntimeException;
34
import org.gvsig.expressionevaluator.Interpreter;
35
import org.gvsig.expressionevaluator.impl.DALFunctions;
36
import org.gvsig.fmap.dal.DALLocator;
37
import org.gvsig.fmap.dal.DataManager;
38
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT_COUNT;
39
import org.gvsig.fmap.dal.SQLBuilder;
40
import static org.gvsig.fmap.dal.SQLBuilder.PROP_FEATURE_TYPE;
41
import static org.gvsig.fmap.dal.SQLBuilder.PROP_SQLBUILDER;
42
import static org.gvsig.fmap.dal.SQLBuilder.PROP_TABLE;
43
import org.gvsig.fmap.dal.feature.Feature;
44
import org.gvsig.fmap.dal.feature.FeatureQuery;
45
import org.gvsig.fmap.dal.feature.FeatureSet;
46
import org.gvsig.fmap.dal.feature.FeatureStore;
47
import org.gvsig.fmap.dal.feature.FeatureType;
48
import org.gvsig.fmap.dal.impl.expressionevaluator.DefaultFeatureExpressionEvaluator;
49
import org.gvsig.tools.dispose.DisposeUtils;
50

    
51
/**
52
 *
53
 * @author jjdelcerro
54
 */
55
@SuppressWarnings("UseSpecificCatch")
56
public class SelectAggregateFunction extends AbstractSelectFunction {
57
    
58
    public static String FUNCTION_SELECT_AGGREGATE = "SELECT_AGGREGATE";
59

    
60
    public SelectAggregateFunction() {
61
        super(DALFunctions.GROUP_DATA_ACCESS,
62
                FUNCTION_SELECT_AGGREGATE,
63
                Range.is(4),
64
                "Returns the aggregate function of features of the table by applying the filter indicated.\n"
65
                + "The syntax is:\n\n"
66
                + "SELECT aggregate_function(column1) FROM table WHERE boolean_expression;\n\n"
67
                + "Indicate a filter expression with WHERE is optional.\n"
68
                + "The SELECT statement must always end with a semicolon.",
69
                "SELECT sum({{column1}}) FROM table WHERE filter ;",
70
                new String[]{
71
                    "table - Name of the table",
72
                    "filter - boolean expression with the filter to apply",
73
                    "aggregate_function - aggregate function to use. Valid functions are SUM, COUNT, MAX, MIN, AVG",
74
                    "column1 - name of column to use in aggregate function",
75
                },
76
                "Object",
77
                true
78
        );
79
    }
80

    
81
    @Override
82
    public boolean isHidden() {
83
        return false;
84
    }
85

    
86
    @Override
87
    public boolean allowConstantFolding() {
88
        return false;
89
    }
90

    
91
    @Override
92
    public boolean useArgumentsInsteadObjects() {
93
        return true;
94
    }
95

    
96
    @Override
97
    public Object call(Interpreter interpreter, Object[] args) throws Exception {
98
        throw new UnsupportedOperationException();
99
    }
100

    
101
    private static final int TABLE = 0;
102
    private static final int WHERE = 1;
103
    private static final int AGGREGATE_FUNCTION = 2;
104
    private static final int AGGREGATE_COLUMN = 3;
105

    
106
    @Override
107
    public Object call(Interpreter interpreter, Codes args) throws Exception {
108

    
109
        String storeName = this.getIdentifier(args, TABLE);
110
        Code where = this.getWhereCode(args, WHERE);
111
        String aggregateFunction = this.getIdentifier(args, AGGREGATE_FUNCTION);
112
        String aggregateColumn = this.getIdentifier(args, AGGREGATE_COLUMN);
113

    
114
        FeatureStore featureStore = null;
115
        FeatureSet set = null;
116
        try {
117
            featureStore = this.getFeatureStore(storeName);
118
            if (featureStore == null) {
119
                throw new ExpressionRuntimeException("Cant locate the feature store '" + storeName + "' in function '" + this.name() + "'.");
120
            }
121
            FeatureQuery query = featureStore.createFeatureQuery();
122
            if (where != null) {
123
                Code where2 = removeOuterTablesReferences(interpreter, where);
124
                ExpressionEvaluator filter = new DefaultFeatureExpressionEvaluator(where2.toString());
125
                filter.toSymbolTable().addSymbolTable(interpreter.getSymbolTable());
126
                query.addFilter(filter);
127
            }
128
            query.retrievesAllAttributes();
129
            query.addAggregate(aggregateFunction, aggregateColumn);
130
            Feature f = featureStore.findFirst(query);
131
            if (f == null){
132
                return null;
133
            }
134
            return f.get(aggregateColumn);
135
        } catch (ExpressionRuntimeException ex) {
136
            throw ex;
137
        } catch (Exception ex) {
138
            throw new ExpressionRuntimeException("Problems calling '" + this.name() + "' function", ex);
139
        } finally {
140
            DisposeUtils.disposeQuietly(set);
141
            DisposeUtils.disposeQuietly(featureStore);
142
        }
143
    }
144

    
145
    @Override
146
    public ExpressionBuilder.Value toValue(ExpressionBuilder builder, Codes args) {
147
        try {
148
            SQLBuilder sqlBuilder = (SQLBuilder) builder.getProperty(PROP_SQLBUILDER);
149
            if(sqlBuilder == null){
150
                return super.toValue(builder, args);
151
            }
152
            FeatureType featureType = null;
153
            SQLBuilder.SelectBuilder select = sqlBuilder.createSelectBuilder();
154
            String builderTableName = (String) builder.getProperty(SQLBuilder.PROP_TABLENAME);
155

    
156
            String storeName = this.getIdentifier(args, TABLE);
157
            Code where = this.getWhereCode(args, WHERE);
158

    
159
            String aggregateFunction = this.getIdentifier(args, AGGREGATE_FUNCTION);
160
            String aggregateColumn = this.getIdentifier(args, AGGREGATE_COLUMN);
161

    
162
            if (storeName != null) {
163
                select.from().table().name(storeName);
164
            }
165

    
166
            SQLBuilder.TableNameBuilder table = select.from().table();
167
            String tableName = table.getName();
168
            
169
            select.column(aggregateColumn).value(builder.function(aggregateFunction, builder.column(aggregateColumn)));
170

    
171
            if (where != null) {
172
                ExpressionBuilder.Value value = where.toValue(builder);
173
                select.where().value(value);
174
                sqlBuilder.setProperties(value, null, SQLBuilder.PROP_ADD_TABLE_NAME_TO_COLUMNS, true);
175
            }
176

    
177
            if (featureType == null) {
178
                if (StringUtils.equalsIgnoreCase(builderTableName, tableName)) {
179
                    featureType = (FeatureType) builder.getProperty(SQLBuilder.PROP_FEATURE_TYPE);
180
                } else {
181
                    DataManager dataManager = DALLocator.getDataManager();
182
                    featureType = dataManager.getStoresRepository().getFeatureType(tableName);
183
                }
184
            }
185

    
186
            sqlBuilder.setProperties(
187
                    select,
188
                    null,
189
                    PROP_FEATURE_TYPE, featureType,
190
                    PROP_TABLE, table
191
            );
192

    
193
            return builder.group(select);
194
        } catch (Exception ex) {
195
            return super.toValue(builder, args);
196
        }
197
    }
198
    
199
}