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 / SelectFromSelectionFunction.java @ 46100

History | View | Annotate | Download (6.24 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 java.util.function.Predicate;
27
import org.apache.commons.lang3.Range;
28
import org.gvsig.expressionevaluator.Code;
29
import org.gvsig.expressionevaluator.Codes;
30
import org.gvsig.expressionevaluator.ExpressionRuntimeException;
31
import org.gvsig.expressionevaluator.Interpreter;
32
import org.gvsig.expressionevaluator.Optimizer;
33
import org.gvsig.expressionevaluator.impl.DALFunctions;
34
import org.gvsig.fmap.dal.feature.FeatureStore;
35
import org.gvsig.fmap.dal.impl.expressionevaluator.DefaultFeatureExpressionEvaluator;
36
import org.gvsig.expressionevaluator.Code.Callable;
37
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT_FROM_SELECTION;
38
import org.gvsig.fmap.dal.feature.FeatureSet;
39
import org.gvsig.tools.evaluator.EvaluatorData;
40
import org.gvsig.tools.evaluator.EvaluatorException;
41
import org.gvsig.tools.util.FilteredIterator;
42
import org.gvsig.tools.util.LimitIterator;
43

    
44
/**
45
 *
46
 * @author jjdelcerro
47
 */
48
@SuppressWarnings("UseSpecificCatch")
49
public class SelectFromSelectionFunction
50
        extends AbstractSelectFunction
51
        implements Optimizer.FunctionOptimizer {
52

    
53
    public SelectFromSelectionFunction() {
54
        super(DALFunctions.GROUP_DATA_ACCESS,
55
                FUNCTION_SELECT_FROM_SELECTION,
56
                Range.is(5),
57
                "Returns a list of features of the table by applying the filter, order and limit indicated.\n"
58
                + "The syntax is:\n\n"
59
                + "SELECT * FROM SELECTION [IF NOT EMPTY] OF table_name WHERE boolean_expression ;\n\n"
60
                + "Indicate a filter expression with WHERE.\n"
61
                + "You can use an asterisk or enter the column names you want to retrieve separated by commas.\n"
62
                + "The SELECT statement must always end with a semicolon.",
63
                "SELECT * FROM SELECTION OF table_name WHERE boolean_expression ;",
64
                new String[]{
65
                    "column_names/asterisk - Names of the columns table to retrieve.",
66
                    "table_name - Name of the table",
67
                    "filter - Optional, boolean expression to apply as filter",
68
                },
69
                "Iterable",
70
                false
71
        );
72
    }
73

    
74
    @Override
75
    public boolean isHidden() {
76
        return false;
77
    }
78

    
79
    @Override
80
    public boolean allowConstantFolding() {
81
        return false;
82
    }
83

    
84
    @Override
85
    public boolean useArgumentsInsteadObjects() {
86
        return true;
87
    }
88

    
89
    @Override
90
    public Object call(Interpreter interpreter, Object[] args) throws Exception {
91
        throw new UnsupportedOperationException();
92
    }
93

    
94
    private static final int COLUMNS = 0;
95
    private static final int TABLE = 1;
96
    private static final int WHERE = 2;
97
    private static final int LIMIT = 3;
98
    private static final int SELECCTION_IF_NOT_EMPTY = 4;
99

    
100
    @Override
101
    public Object call(Interpreter interpreter, Codes args) throws Exception {
102

    
103
        Code columns = getTupleOrNull(args, COLUMNS);
104
        String storeName = this.getTableName(args, TABLE);
105
        Code where = this.getWhereCode(args, WHERE);
106
        Number limit = (Number) getObject(interpreter, args, LIMIT);
107
        Object selection_if_not_empty = getObject(interpreter, args, SELECCTION_IF_NOT_EMPTY);
108
        
109
        
110
        FeatureStore featureStore;
111
        try {
112
            featureStore = this.getFeatureStore(storeName);
113
            if (featureStore == null) {
114
                throw new ExpressionRuntimeException("Cant locate the feature store '" + storeName + "' in function '" + this.name() + "'.");
115
            }
116
            Iterable features = featureStore.getFeatureSelection();
117
            if( ((FeatureSet)features).isEmpty() ) {
118
                if( selection_if_not_empty != null ) {
119
                    features = featureStore.getFeatureSet();
120
                    // En este caso habria que optimizar el where, pero de 
121
                    // momento asi va, aunque lento.
122
                }                
123
            }
124
            if (where != null) {
125
                final Iterable baseSelection = features;
126
                final DefaultFeatureExpressionEvaluator evaluator = new DefaultFeatureExpressionEvaluator(where.toString());
127
                evaluator.toSymbolTable().addSymbolTable(interpreter.getSymbolTable());
128
                final Predicate filter = (Predicate) (Object t) -> {
129
                    try {
130
                        return (boolean) evaluator.evaluate((EvaluatorData) t);
131
                    } catch (EvaluatorException ex1) {
132
                        throw new ExpressionRuntimeException("Can't evaluate expression for row.", ex1);
133
                    }
134
                };
135
                features = (Iterable) () -> new FilteredIterator(baseSelection.iterator(), filter);
136
            }
137
            if( limit!=null ) {
138
                final Iterable baseSelection = features;
139
                features = (Iterable) () -> new LimitIterator(baseSelection.iterator(), limit.longValue());
140
            }
141
            return features;
142

    
143
        } catch (ExpressionRuntimeException ex) {
144
            throw ex;
145
        } catch (Exception ex) {
146
            throw new ExpressionRuntimeException("Problems calling '" + this.name() + "' function", ex);
147
        }
148
    }
149

    
150
    @Override
151
    public Code optimize(Optimizer optimizer, Callable caller) {
152
        return caller; // Don't optimize SELECT
153
    }
154

    
155
}