Revision 46100

View differences:

trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.api/src/main/java/org/gvsig/fmap/dal/DataManager.java
101 101
    public static final String FUNCTION_INSERT_INTO_TABLE = "INSERT_INTO_TABLE";
102 102
    public static final String FUNCTION_CREATE_TABLE = "CREATE_TABLE";
103 103
    public static final String FUNCTION_CREATE_TABLE_STRUCTURE = "CREATE_TABLE_STRUCTURE";
104
    public static final String FUNCTION_SELECT_FROM_SELECTION = "SELECTFROMSELECTION";
105
    public static final String FUNCTION_SELECT_COUNT_FROM_SELECTION = "SELECTCOUNTFROMSELECTION";
104 106
    
105 107
    public static final String DAL_PREFERRED_COLUMNS = "DAL.Preferred.Columns";
106 108
    
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/symboltable/DALSymbolTable.java
36 36
import org.gvsig.expressionevaluator.impl.function.dataaccess.InsertIntoTableFunction;
37 37
import org.gvsig.expressionevaluator.impl.function.dataaccess.IsSelectedCurrentRowFunction;
38 38
import org.gvsig.expressionevaluator.impl.function.dataaccess.RowTagFunction;
39
import org.gvsig.expressionevaluator.impl.function.dataaccess.SelectCountFromSelectionFunction;
39 40
import org.gvsig.expressionevaluator.impl.function.dataaccess.SelectCountFunction;
41
import org.gvsig.expressionevaluator.impl.function.dataaccess.SelectFromSelectionFunction;
40 42
import org.gvsig.expressionevaluator.impl.function.dataaccess.SelectFunction;
41 43
import org.gvsig.expressionevaluator.impl.function.dataaccess.SetRowTagFunction;
42 44
import org.gvsig.expressionevaluator.spi.AbstractSymbolTable;
......
71 73
        this.addFunction(new SetRowTagFunction());
72 74
        this.addFunction(new CreateTableFunction());
73 75
        this.addFunction(new CreateTableStructureFunction());
74
    }    
76
        this.addFunction(new SelectFromSelectionFunction());
77
        this.addFunction(new SelectCountFromSelectionFunction());
78
    }     
75 79
}
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
23 23
 */
24 24
package org.gvsig.expressionevaluator.impl.function.dataaccess;
25 25

  
26
import java.util.ArrayList;
27
import java.util.HashSet;
28 26
import java.util.List;
29
import java.util.Objects;
30
import java.util.Set;
31 27
import org.apache.commons.lang3.Range;
32
import org.apache.commons.lang3.StringUtils;
33
import org.apache.commons.lang3.tuple.ImmutablePair;
34
import org.apache.commons.lang3.tuple.Pair;
35 28
import org.gvsig.expressionevaluator.Code;
36
import org.gvsig.expressionevaluator.CodeBuilder;
37 29
import org.gvsig.expressionevaluator.Codes;
38
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_GETATTR;
39
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_TUPLE;
40 30
import org.gvsig.expressionevaluator.ExpressionRuntimeException;
41
import org.gvsig.expressionevaluator.ExpressionUtils;
42 31
import org.gvsig.expressionevaluator.Interpreter;
43 32
import org.gvsig.expressionevaluator.Optimizer;
44
import org.gvsig.expressionevaluator.SymbolTable;
45 33
import org.gvsig.expressionevaluator.impl.DALFunctions;
46 34
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT;
47
import org.gvsig.fmap.dal.DataStore;
48 35
import org.gvsig.expressionevaluator.ExpressionEvaluator;
49
import static org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable.SYMBOL_CURRENT_TABLE;
50
import org.gvsig.fmap.dal.expressionevaluator.TableAttributeHandler;
51 36
import org.gvsig.fmap.dal.feature.Feature;
52 37
import org.gvsig.fmap.dal.feature.FeatureQuery;
53 38
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
......
136 121
                queryOrder.add(member, mode);
137 122
            }
138 123
        }
139
        FeatureStore featureStore = null;
124
        FeatureStore featureStore;
140 125
        try {
141 126
            featureStore = this.getFeatureStore(storeName);
142 127
            if (featureStore == null) {
......
165 150
        } catch (ExpressionRuntimeException ex) {
166 151
            throw ex;
167 152
        } catch (Exception ex) {
168
            throw new ExpressionRuntimeException("Problems calling '" + FUNCTION_SELECT + "' function", ex);
153
            throw new ExpressionRuntimeException("Problems calling '" + this.name() + "' function", ex);
169 154
        }
170 155
    }
171 156

  
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/SelectCountFromSelectionFunction.java
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.impl.DALFunctions;
33
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT_COUNT_FROM_SELECTION;
34
import org.gvsig.fmap.dal.feature.FeatureSet;
35
import org.gvsig.fmap.dal.feature.FeatureStore;
36
import org.gvsig.fmap.dal.impl.expressionevaluator.DefaultFeatureExpressionEvaluator;
37
import org.gvsig.tools.evaluator.EvaluatorData;
38
import org.gvsig.tools.evaluator.EvaluatorException;
39
import org.gvsig.tools.util.ContainerUtils;
40
import org.gvsig.tools.util.FilteredIterator;
41

  
42
/**
43
 *
44
 * @author jjdelcerro
45
 */
46
@SuppressWarnings("UseSpecificCatch")
47
public class SelectCountFromSelectionFunction extends AbstractSelectFunction {
48

  
49
    public SelectCountFromSelectionFunction() {
50
        super(DALFunctions.GROUP_DATA_ACCESS,
51
                FUNCTION_SELECT_COUNT_FROM_SELECTION,
52
                Range.is(3),
53
                "Returns the number of features of the table by applying the filter indicated.\n"
54
                + "The syntax is:\n\n"
55
                + "SELECT COUNT(*) FROM SELECTION [IF NOT EMPTY] OF table WHERE boolean_expression;\n\n"
56
                + "Indicate a filter expression with WHERE is optional.\n"
57
                + "The SELECT statement must always end with a semicolon.",
58
                "SELECT COUNT(*) FROM {{table}} WHERE filter ;",
59
                new String[]{
60
                    "table - Name of the table",
61
                    "filter - boolean expression with the filter to apply",},
62
                "Long",
63
                false
64
        );
65
    }
66

  
67
    @Override
68
    public boolean isHidden() {
69
        return false;
70
    }
71

  
72
    @Override
73
    public boolean allowConstantFolding() {
74
        return false;
75
    }
76

  
77
    @Override
78
    public boolean useArgumentsInsteadObjects() {
79
        return true;
80
    }
81

  
82
    @Override
83
    public Object call(Interpreter interpreter, Object[] args) throws Exception {
84
        throw new UnsupportedOperationException();
85
    }
86

  
87
    private static final int TABLE = 0;
88
    private static final int WHERE = 1;
89
    private static final int SELECCTION_IF_NOT_EMPTY = 2;
90

  
91
    @Override
92
    public Object call(Interpreter interpreter, Codes args) throws Exception {
93

  
94
        String storeName = this.getTableName(args, TABLE);
95
        Code where = this.getWhereCode(args, WHERE);
96
        Object selection_if_not_empty = getObject(interpreter, args, SELECCTION_IF_NOT_EMPTY);
97
        
98
        FeatureStore featureStore;
99
        try {
100
            featureStore = this.getFeatureStore(storeName);
101
            if (featureStore == null) {
102
                throw new ExpressionRuntimeException("Cant locate the feature store '" + storeName + "' in function '" + this.name() + "'.");
103
            }
104
            Iterable features = featureStore.getFeatureSelection();
105
            if( ((FeatureSet)features).isEmpty() ) {
106
                if( selection_if_not_empty != null ) {
107
                    features = featureStore.getFeatureSet();
108
                    // En este caso habria que optimizar el where, pero de 
109
                    // momento asi va, aunque lento.
110
                }                
111
            }
112
            if (where != null) {
113
                final Iterable baseSelection = features;
114
                final DefaultFeatureExpressionEvaluator evaluator = new DefaultFeatureExpressionEvaluator(where.toString());
115
                evaluator.toSymbolTable().addSymbolTable(interpreter.getSymbolTable());
116
                final Predicate filter = (Predicate) (Object t) -> {
117
                    try {
118
                        return (boolean) evaluator.evaluate((EvaluatorData) t);
119
                    } catch (EvaluatorException ex1) {
120
                        throw new ExpressionRuntimeException("Can't evaluate expression for row.", ex1);
121
                    }
122
                };
123
                features = (Iterable) () -> new FilteredIterator(baseSelection.iterator(), filter);
124
            }
125
            return ContainerUtils.size64(features);
126

  
127
        } catch (ExpressionRuntimeException ex) {
128
            throw ex;
129
        } catch (Exception ex) {
130
            throw new ExpressionRuntimeException("Problems calling '" + this.name() + "' function", ex);
131
        }
132
    }
133

  
134
}
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
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
}
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/grammars/DataAccessGrammarFactory.java
46 46
import org.gvsig.fmap.dal.DataManager;
47 47
import static org.gvsig.fmap.dal.DataManager.FUNCTION_CREATE_TABLE;
48 48
import static org.gvsig.fmap.dal.DataManager.FUNCTION_CREATE_TABLE_STRUCTURE;
49
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT_COUNT_FROM_SELECTION;
50
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT_FROM_SELECTION;
49 51

  
50 52
/**
51 53
 *
......
238 240
            theGrammar.addStatement(createSelectCountStatement(theGrammar));
239 241
            theGrammar.addStatement(createSelectStatement(theGrammar));
240 242
//            theGrammar.addStatement(createUpdateStatement(theGrammar));
243
            theGrammar.addStatement(createSelectCountFromSelectionStatement(theGrammar));
244
            theGrammar.addStatement(createSelectFromSelectionStatement(theGrammar));
241 245

  
242 246
            this.grammar = theGrammar;
243 247
        }
......
368 372
        return stmt;
369 373
    }
370 374

  
375
    private Statement createSelectFromSelectionStatement(Grammar theGrammar) {
376
        Statement stmt;
377
//
378
//      SELECT * | (column1, column2,...) 
379
//          FROM SELECTION OF table_name
380
//          WHERE expression
381
//        
382
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
383
        CodeBuilder codeBuilder = manager.createCodeBuilder();
371 384

  
385
        stmt = theGrammar.createStatement("SELECTFROMSELECTION");
386
        stmt.addRule(stmt.require_any_token("SELECT"));
387
        stmt.addRule(stmt.optional_any_token("*")
388
                .addRuleOnTrue(stmt.set_expression("COLUMNS", codeBuilder.tuple()))
389
                .addRuleOnFalse(stmt.require_identifiers(",").capture_as("COLUMNS"))
390
        );
391
        stmt.addRule(stmt.require_any_token("FROM"));
392
        stmt.addRule(stmt.require_any_token("SELECTION"));
393
        stmt.addRule(stmt.optional_any_token("IF")
394
                .addRuleOnTrue(stmt.require_tokens("NOT", "EMPTY").capture_as("IF_NOT_EMPTY"))
395
        );
396
        stmt.addRule(stmt.optional_any_token("OF"));
397
        stmt.addRule(stmt.require_expression().capture_as("TABLE"));
398
        stmt.addRule(stmt.optional_any_token("WHERE")
399
                .addRuleOnTrue(stmt.require_expression().capture_as("WHERE"))
400
        );
401
        stmt.addRule(stmt.optional_any_token("LIMIT")
402
                .addRuleOnTrue(stmt.require_expression().capture_as("LIMIT"))
403
        );
404
        stmt.addRule(stmt.optional_any_token(";"));
405
        stmt.code(
406
                FUNCTION_SELECT_FROM_SELECTION,
407
                stmt.args_names("COLUMNS", "TABLE", "WHERE", "LIMIT","IF_NOT_EMPTY")
408
        );
409

  
410
        return stmt;
411
    }
412

  
372 413
    private Statement createInsertIntoTableSelectStatement(Grammar theGrammar) {
373 414
        Statement stmt;
374 415
//
......
461 502
        return stmt;
462 503
    }
463 504

  
505
    private Statement createSelectCountFromSelectionStatement(Grammar theGrammar) {
506
        Statement stmt;
507
//
508
//      SELECT COUNT(*) FROM SELECTION IF NOT IS EMPTY OF table_name WHERE expression
509
//        
510
        stmt = theGrammar.createStatement("SELECT_COUNT_FROM_SELECTION");
511
        stmt.addRule(stmt.require_any_token("SELECT"));
512
        stmt.addRule(stmt.require_any_token("COUNT"));
513
        stmt.addRule(stmt.require_any_token("("));
514
        stmt.addRule(stmt.require_any_token("*"));
515
        stmt.addRule(stmt.require_any_token(")"));
516
        stmt.addRule(stmt.require_any_token("FROM"));
517
        stmt.addRule(stmt.require_any_token("SELECTION"));
518
        stmt.addRule(stmt.optional_any_token("IF")
519
                .addRuleOnTrue(stmt.require_tokens("NOT", "EMPTY").capture_as("IF_NOT_EMPTY"))
520
        );
521
        stmt.addRule(stmt.require_any_token("OF"));
522
        stmt.addRule(stmt.require_expression().capture_as("TABLE"));
523
        stmt.addRule(stmt.optional_any_token("WHERE")
524
                .addRuleOnTrue(stmt.require_expression().capture_as("WHERE"))
525
        );
526
        stmt.addRule(stmt.require_any_token(";"));
527
        stmt.code(
528
                FUNCTION_SELECT_COUNT_FROM_SELECTION,
529
                stmt.args_names("TABLE", "WHERE", "IF_NOT_EMPTY")
530
        );
531
        return stmt;
532
    }
533

  
464 534
    private Statement createCreateTableStatement(Grammar theGrammar) {
465 535
        Statement stmt;
466 536
//

Also available in: Unified diff