Revision 44750

View differences:

trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.spi/src/main/java/org/gvsig/fmap/dal/spi/AbstractDataParameters.java
30 30
import org.apache.commons.io.FileUtils;
31 31
import org.apache.commons.io.FilenameUtils;
32 32
import org.apache.commons.lang3.StringUtils;
33
import org.apache.commons.lang3.mutable.MutableInt;
33 34
import org.cresques.cts.ICRSFactory;
34 35
import org.cresques.cts.IProjection;
35 36
import org.gvsig.fmap.crs.CRSFactory;
......
52 53
import org.gvsig.tools.persistence.PersistenceManager;
53 54
import org.gvsig.tools.persistence.PersistentState;
54 55
import org.gvsig.tools.persistence.exception.PersistenceException;
56
import org.gvsig.tools.persistence.xml.XMLPersistenceManager;
55 57

  
56 58
/**
57 59
 * @author jmvivo
......
230 232
    @Override
231 233
    public byte[] toByteArray() {
232 234
            try {
233
            PersistenceManager persistenceManager = ToolsLocator.getPersistenceManager();
235
//            PersistenceManager persistenceManager = ToolsLocator.getPersistenceManager();
236
            PersistenceManager persistenceManager = new XMLPersistenceManager();
234 237
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
235
            PersistentState state = persistenceManager.getState(this);
238
            PersistentState state = persistenceManager.getState(this, false, new MutableInt(1));
236 239
            persistenceManager.saveState(state, stream);
237 240
            return stream.toByteArray();
238 241
        } catch (Exception ex) {
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.impl/src/test/java/org/gvsig/expressionevaluator/TestGrammarCompiler.java
67 67

  
68 68
        Code code = compiler.compileExpression(source.toString());
69 69
        link(code);
70
        assertEquals("SELECT(TABLE:'countries')", code.toString());
70
        assertEquals("SELECT(NULL, \"countries\", NULL, TUPLE(), TUPLE(), NULL)", code.toString());
71 71
    }
72 72

  
73
    public void testSelect1() {
74
        StringBuilder source = new StringBuilder();
75
        source.append("SELECT * FROM countries");
76

  
77
        Compiler compiler = createCompiler();
78

  
79
        Code code = compiler.compileExpression(source.toString());
80
        link(code);
81
        assertEquals("SELECT(NULL, \"countries\", NULL, TUPLE(), TUPLE(), NULL)", code.toString());
82
    }
83
    
73 84
    public void testSelect2() {
74 85
        StringBuilder source = new StringBuilder();
75 86
        source.append("BEGIN ");
76 87
        source.append("  SET X = 0; ");
77
        source.append("  FOR row in (SELECT * FROM countries;) ");
88
        source.append("  FOR row in (SELECT * FROM countries;) "); // Con ;
78 89
        source.append("    BEGIN ");
79 90
        source.append("      IF row.LASTCENSUS > 0 THEN ");
80 91
        source.append("        SET X = X + row.LASTCENSUS ");
......
86 97

  
87 98
        Code code = compiler.compileExpression(source.toString());
88 99
        link(code);
89
        assertEquals("BLOCK(LET('X', 0), FOREACH('row', SELECT(TABLE:'countries'), IFF((\"row\".\"LASTCENSUS\" > 0), LET('X', (\"X\" + \"row\".\"LASTCENSUS\")))))", code.toString());
100
        assertEquals("BLOCK(LET('X', 0), FOREACH('row', SELECT(NULL, \"countries\", NULL, TUPLE(), TUPLE(), NULL), IFF((\"row\".\"LASTCENSUS\" > 0), LET('X', (\"X\" + \"row\".\"LASTCENSUS\")))))", code.toString());
90 101
    }
91 102

  
103
    public void testSelect3() {
104
        StringBuilder source = new StringBuilder();
105
        source.append("BEGIN ");
106
        source.append("  SET X = 0; ");
107
        source.append("  FOR row in (SELECT * FROM countries) "); // Sin ;
108
        source.append("    BEGIN ");
109
        source.append("      IF row.LASTCENSUS > 0 THEN ");
110
        source.append("        SET X = X + row.LASTCENSUS ");
111
        source.append("      END IF ");
112
        source.append("    END FOR ");
113
        source.append("END");
114

  
115
        Compiler compiler = createCompiler();
116

  
117
        Code code = compiler.compileExpression(source.toString());
118
        link(code);
119
        assertEquals("BLOCK(LET('X', 0), FOREACH('row', SELECT(NULL, \"countries\", NULL, TUPLE(), TUPLE(), NULL), IFF((\"row\".\"LASTCENSUS\" > 0), LET('X', (\"X\" + \"row\".\"LASTCENSUS\")))))", code.toString());
120
    }
121

  
92 122
    public void testSelectWhere() {
93 123
        StringBuilder source = new StringBuilder();
94 124
        source.append("SELECT * FROM countries  ");
......
98 128

  
99 129
        Code code = compiler.compileExpression(source.toString());
100 130
        link(code);
101
        assertEquals("SELECT(TABLE:'countries', WHERE:(\"LASTCENSUS\" > 0))", code.toString());
131
        assertEquals("SELECT(NULL, \"countries\", (\"LASTCENSUS\" > 0), TUPLE(), TUPLE(), NULL)", code.toString());
102 132
    }
103 133

  
104 134
    public void testSelectCountWhere() {
......
110 140

  
111 141
        Code code = compiler.compileExpression(source.toString());
112 142
        link(code);
113
        assertEquals("SELECT_COUNT(TABLE:'countries', WHERE:(\"LASTCENSUS\" > 0))", code.toString());
143
        assertEquals("SELECT_COUNT(\"countries\", (\"LASTCENSUS\" > 0))", code.toString());
114 144
    }
115 145

  
116 146
    public void testSelectWhere2() {
......
122 152

  
123 153
        Code code = compiler.compileExpression(source.toString());
124 154
        link(code);
125
        assertEquals("SELECT(TABLE:'countries', WHERE:(\"countries\".\"LASTCENSUS\" > 0))", code.toString());
155
        assertEquals("SELECT(NULL, \"countries\", (\"countries\".\"LASTCENSUS\" > 0), TUPLE(), TUPLE(), NULL)", code.toString());
126 156
    }
127 157

  
128 158
    public void testSelectOrder() {
......
134 164

  
135 165
        Code code = compiler.compileExpression(source.toString());
136 166
        link(code);
137
        assertEquals("SELECT(TABLE:'countries', ORDER1:\"CONTINENT\", ORDER2:\"LASTCENSUS\", ORDER_MODE1:TRUE, ORDER_MODE2:FALSE)", code.toString());
167
        assertEquals("SELECT(NULL, \"countries\", NULL, TUPLE(\"CONTINENT\", \"LASTCENSUS\"), TUPLE(TRUE, FALSE), NULL)", code.toString());
138 168
    }
139 169

  
140 170
    public void testSelectWhereOrder() {
......
147 177

  
148 178
        Code code = compiler.compileExpression(source.toString());
149 179
        link(code);
150
        assertEquals("SELECT(TABLE:'countries', WHERE:(\"LASTCENSUS\" > 0), ORDER1:\"ID\", ORDER_MODE1:TRUE)", code.toString());
180
        assertEquals("SELECT(NULL, \"countries\", (\"LASTCENSUS\" > 0), TUPLE(\"ID\"), TUPLE(TRUE), NULL)", code.toString());
151 181
    }
152 182

  
153 183
    public void testSelectWhereOrderLimit() {
......
161 191

  
162 192
        Code code = compiler.compileExpression(source.toString());
163 193
        link(code);
164
        assertEquals("SELECT(TABLE:'countries', WHERE:(\"LASTCENSUS\" > 0), ORDER1:\"LASTCENSUS\", ORDER_MODE1:FALSE, LIMIT:3)", code.toString());
194
        assertEquals("SELECT(NULL, \"countries\", (\"LASTCENSUS\" > 0), TUPLE(\"LASTCENSUS\"), TUPLE(FALSE), 3)", code.toString());
165 195
    }
166 196

  
167 197
    public void testSelectLimit() {
......
173 203

  
174 204
        Code code = compiler.compileExpression(source.toString());
175 205
        link(code);
176
        assertEquals("SELECT(TABLE:'countries', LIMIT:3)", code.toString());
206
        assertEquals("SELECT(NULL, \"countries\", NULL, TUPLE(), TUPLE(), 3)", code.toString());
177 207
    }
178 208

  
179 209
    public void testExists() {
......
204 234
        String id = "????????????????????????????????";
205 235
        String s = code.toString();
206 236
        s = s.substring(0, s.length()-id.length()-2)+id+s.substring(s.length()-2);
207
        assertEquals("EXISTS(SELECT(TABLE:'countries', WHERE:(\"countries\".\"LASTCENSUS\" > 0)), 'EXISTS????????????????????????????????')", s);
237
        assertEquals("EXISTS(SELECT(TUPLE(1), \"countries\", (\"countries\".\"LASTCENSUS\" > 0), TUPLE(), TUPLE(), NULL), 'EXISTS????????????????????????????????')", s);
208 238
    }
209 239

  
240
    public void testExistsSelect2() {
241
        StringBuilder source = new StringBuilder();
242
        source.append("EXISTS(");
243
        source.append(" SELECT 1 FROM countries");
244
        source.append("   WHERE countries.LASTCENSUS > 0 ");
245
        source.append(")");
246

  
247
        Compiler compiler = createCompiler();
248

  
249
        Code code = compiler.compileExpression(source.toString());
250
        link(code);
251
        String id = "????????????????????????????????";
252
        String s = code.toString();
253
        s = s.substring(0, s.length()-id.length()-2)+id+s.substring(s.length()-2);
254
        assertEquals("EXISTS(SELECT(TUPLE(1), \"countries\", (\"countries\".\"LASTCENSUS\" > 0), TUPLE(), TUPLE(), NULL), 'EXISTS????????????????????????????????')", s);
255
    }
256

  
210 257
    public void testExistsSelectLimit1() {
211 258
        StringBuilder source = new StringBuilder();
212 259
        source.append("EXISTS(");
......
222 269
        String id = "????????????????????????????????";
223 270
        String s = code.toString();
224 271
        s = s.substring(0, s.length()-id.length()-2)+id+s.substring(s.length()-2);
225
        assertEquals("EXISTS(SELECT(TABLE:'countries', WHERE:(\"countries\".\"LASTCENSUS\" > 0), LIMIT:1), 'EXISTS????????????????????????????????')", s);
272
        assertEquals("EXISTS(SELECT(TUPLE(1), \"countries\", (\"countries\".\"LASTCENSUS\" > 0), TUPLE(), TUPLE(), 1), 'EXISTS????????????????????????????????')", s);
226 273
    }
227 274

  
228 275
    public void testExistsSelectLimit2() {
......
245 292
        String id = "????????????????????????????????";
246 293
        String s = code.toString();
247 294
        s = s.substring(0, s.length()-id.length()-2)+id+s.substring(s.length()-2);
248
        assertEquals("EXISTS(SELECT(TABLE:'countries', WHERE:((\"continents\".\"NAME\" = \"countries\".\"CONTINENT\") AND (\"countries\".\"LASTCENSUS\" < 0)), LIMIT:1), 'EXISTS????????????????????????????????')", s);
295
        assertEquals("EXISTS(SELECT(TUPLE(1), \"countries\", ((\"continents\".\"NAME\" = \"countries\".\"CONTINENT\") AND (\"countries\".\"LASTCENSUS\" < 0)), TUPLE(), TUPLE(), 1), 'EXISTS????????????????????????????????')", s);
249 296
    }
250 297

  
251 298
    public void testExistsSelectLimit3() {
......
258 305
        source.append("   WHERE ");
259 306
        source.append("     continents.NAME = countries.CONTINENT AND ");
260 307
        source.append("     countries.LASTCENSUS < 0 ");
261
        source.append("   LIMIT 1; ");
308
        source.append("   LIMIT 1 ");
262 309
        source.append(" ,");
263 310
        source.append(" 'patata'");
264 311
        source.append(")");
......
267 314

  
268 315
        Code code = compiler.compileExpression(source.toString());
269 316
        link(code);
270
        assertEquals("EXISTS(SELECT(TABLE:'countries', WHERE:((\"continents\".\"NAME\" = \"countries\".\"CONTINENT\") AND (\"countries\".\"LASTCENSUS\" < 0)), LIMIT:1), 'patata')", code.toString());
317
        assertEquals("EXISTS(SELECT(TUPLE(1), \"countries\", ((\"continents\".\"NAME\" = \"countries\".\"CONTINENT\") AND (\"countries\".\"LASTCENSUS\" < 0)), TUPLE(), TUPLE(), 1), 'patata')", code.toString());
271 318
    }
272 319

  
273 320
    public void testExistsSelectLimit4() {
274 321
        StringBuilder source = new StringBuilder();
275 322
        source.append("EXISTS(");
276 323
        source.append(" SELECT(");
277
        source.append("   TABLE:'countries', ");
278
        source.append("   WHERE:(countries.LASTCENSUS > 0), ");
279
        source.append("   LIMIT:1 ");
324
        source.append("   TUPLE(1), ");
325
        source.append("   countries, ");
326
        source.append("   (countries.LASTCENSUS > 0), ");
327
        source.append("   TUPLE(), ");
328
        source.append("   TUPLE(), ");
329
        source.append("   1 ");
280 330
        source.append("  ) ");
281 331
        source.append(" , ");
282 332
        source.append(" 'EXISTS1234567890ABCDEFGHHIJKLMNOPQRSTU' ");
......
289 339
        String id = "????????????????????????????????";
290 340
        String s = code.toString();
291 341
        s = s.substring(0, s.length()-id.length()-2)+id+s.substring(s.length()-2);
292
        assertEquals("EXISTS(SELECT(TABLE:'countries', WHERE:(\"countries\".\"LASTCENSUS\" > 0), LIMIT:1), 'EXISTS????????????????????????????????')", s);
342
        assertEquals("EXISTS(SELECT(TUPLE(1), \"countries\", (\"countries\".\"LASTCENSUS\" > 0), TUPLE(), TUPLE(), 1), 'EXISTS????????????????????????????????')", s);
293 343
    }
294 344

  
295 345
}
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/DefaultDALExpressionBuilder.java
1
package org.gvsig.expressionevaluator.impl;
2

  
3
import java.util.UUID;
4
import org.gvsig.expressionevaluator.ExpressionBuilder;
5
import org.gvsig.expressionevaluator.ExpressionBuilder.Value;
6
import org.gvsig.expressionevaluator.ExpressionUtils;
7
import static org.gvsig.fmap.dal.DataManager.FUNCTION_CURRENT_ROW;
8
import static org.gvsig.fmap.dal.DataManager.FUNCTION_CURRENT_STORE;
9
import static org.gvsig.fmap.dal.DataManager.FUNCTION_EXISTS;
10
import static org.gvsig.fmap.dal.DataManager.FUNCTION_FOREING_VALUE;
11
import static org.gvsig.fmap.dal.DataManager.FUNCTION_ISSELECTED_CURRENT_ROW;
12
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT;
13
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT_COUNT;
14
import org.gvsig.fmap.dal.expressionevaluator.DALExpressionBuilder;
15

  
16
/**
17
 *
18
 * @author jjdelcerro
19
 */
20
public class DefaultDALExpressionBuilder implements DALExpressionBuilder {
21

  
22
  private class DefaultSelectBuilder implements SelectBuilder {
23
    
24
    private Value columns;
25
    private String tableName;
26
    private Value where;
27
    private Long limit;
28
    private final ExpressionBuilder.Function order;
29
    private final ExpressionBuilder.Function order_mode;
30
    
31
    public DefaultSelectBuilder() {
32
      this.columns = expression().tuple(); // ALL === empty tuple
33
      this.where = null;
34
      this.order = expression().tuple();
35
      this.order_mode = expression().tuple();
36
      this.limit = null;
37
    }
38

  
39
    @Override
40
    public SelectBuilder column(String name) {
41
      ((ExpressionBuilder.Function)columns).parameter(expression().column(name));
42
      return this;
43
    }
44

  
45
    @Override
46
    public SelectBuilder column_all() {
47
      this.columns = expression().tuple(); // ALL === empty tuple
48
      return this;
49
    }
50

  
51
    @Override
52
    public SelectBuilder table(String tableName) {
53
      this.tableName = tableName;
54
      return this;
55
    }
56

  
57
    @Override
58
    public SelectBuilder where(ExpressionBuilder.Value where) {
59
      this.where = where;
60
      return this;
61
    }
62

  
63
    @Override
64
    public SelectBuilder order(String columnName, boolean asc) {
65
      this.order.parameter(expression().variable(columnName));
66
      this.order_mode.parameter(expression().constant(asc));
67
      return this;
68
    }
69

  
70
    @Override
71
    public SelectBuilder limit(long limit) {
72
      this.limit = limit;
73
      return this;
74
    }
75

  
76
    @Override
77
    public ExpressionBuilder.Value toValue() {
78
      ExpressionBuilder.Function select = expression().function(FUNCTION_SELECT);
79
      
80
      select.parameter(columns);
81
      select.parameter(expression().variable(tableName));
82
      select.parameter(where);
83
      select.parameter(order);
84
      select.parameter(order_mode);
85
      select.parameter(expression().constant(limit));
86
      
87
      return select;
88
    }
89

  
90
    @Override
91
    public String toString() {
92
      return this.toValue().toString();
93
    }
94
    
95
  }
96
  
97
  private class DefaultSelectCountBuilder implements SelectCountBuilder {
98
    
99
    private String tableName;
100
    private Value where;
101
    
102
    public DefaultSelectCountBuilder() {
103
    }
104

  
105
    @Override
106
    public SelectCountBuilder table(String tableName) {
107
      this.tableName = tableName;
108
      return this;
109
    }
110

  
111
    @Override
112
    public SelectCountBuilder where(ExpressionBuilder.Value where) {
113
      this.where = where;
114
      return this;
115
    }
116

  
117
    @Override
118
    public ExpressionBuilder.Value toValue() {
119
      ExpressionBuilder.Function select = expression().function(FUNCTION_SELECT_COUNT);
120
      
121
      select.parameter(expression().variable(tableName));
122
      if( where != null ) {
123
        select.parameter(where);
124
      }
125
      return select;
126
    }
127

  
128
    @Override
129
    public String toString() {
130
      return this.toValue().toString();
131
    }
132
    
133
  }
134

  
135
  private ExpressionBuilder expressionBuilder;
136
  
137
  @Override
138
  public ExpressionBuilder expression() {
139
    if( this.expressionBuilder == null ) {
140
      this.expressionBuilder = ExpressionUtils.createExpressionBuilder();
141
    }
142
    return this.expressionBuilder;
143
  }
144
  
145
  @Override
146
  public SelectBuilder select() {
147
    return new DefaultSelectBuilder();
148
  }
149

  
150
  @Override
151
  public SelectCountBuilder select_count() {
152
    return new DefaultSelectCountBuilder();
153
  }
154

  
155
  @Override
156
  public ExpressionBuilder.Function exists(Value list) {
157
    return exists(list, null);
158
  }
159

  
160
  @Override
161
  public ExpressionBuilder.Function exists(Value list, String exists_id) {
162
      if( exists_id==null ) {
163
        exists_id = "EXISTS"+UUID.randomUUID().toString().replaceAll("-", "");
164
      }
165
      ExpressionBuilder.Function exists = expression().function(
166
              FUNCTION_EXISTS,
167
              list, 
168
              expression().constant(exists_id)
169
      );
170
      return exists;
171
  }
172

  
173
  @Override
174
  public ExpressionBuilder.Function foreing_value(String attrlocal, String attrforeing) {
175
    ExpressionBuilder.Function foreing_value = expression().function(
176
          FUNCTION_FOREING_VALUE,
177
          expression().tuple(
178
                  expression().constant(attrlocal),
179
                  expression().constant(attrforeing)
180
          )
181
    );
182
    return foreing_value;
183
  }
184
  
185
  @Override
186
  public ExpressionBuilder.Function current_row() {
187
    return expression().function(FUNCTION_CURRENT_ROW);
188
  }
189
  
190
  @Override
191
  public ExpressionBuilder.Function current_table() {
192
    return expression().function(FUNCTION_CURRENT_STORE);
193
  }
194
  
195
  @Override
196
  public ExpressionBuilder.Function isselected_current_row() {
197
    return expression().function(FUNCTION_ISSELECTED_CURRENT_ROW);
198
  }
199
  
200
}
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/FeatureSymbolTableImpl.java
23 23
 */
24 24
package org.gvsig.expressionevaluator.impl.symboltable;
25 25

  
26
import org.gvsig.fmap.dal.expressionevaluator.TableAttributeHandler;
26 27
import org.apache.commons.lang3.Range;
27 28
import org.apache.commons.lang3.StringUtils;
28 29
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
......
40 41
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
41 42
import org.gvsig.fmap.dal.feature.FeatureStore;
42 43
import org.gvsig.fmap.dal.feature.FeatureType;
43
import org.gvsig.tools.dynobject.DynObject;
44
import org.gvsig.tools.dynobject.DynObjectAdapter;
45
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
46 44

  
47 45
/**
48 46
 *
......
50 48
 */
51 49
@SuppressWarnings("UseSpecificCatch")
52 50
public class FeatureSymbolTableImpl extends AbstractSymbolTable implements FeatureSymbolTable {
51
  private static final String DAL_SYMBOL_TABLE_FEATURE = "DAL.SymbolTable.Feature";
53 52

  
54 53
  private final Function current_row;
55 54
  private Feature feature;
56 55
  private FeatureType type;
57 56
  private String storeName;
58
  private DynObject storeAdapter;
57
  private final TableAttributeHandler storeAttributeHandler;
59 58

  
60 59
  @SuppressWarnings("OverridableMethodCallInConstructor")
61 60
  public FeatureSymbolTableImpl() {
62
    super(DataManager.DAL_SYMBOL_TABLE_FEATURE);
61
    super(DAL_SYMBOL_TABLE_FEATURE);
63 62
    this.current_row = new AbstractFunction(
64 63
            DALFunctions.GROUP_DATA_ACCESS,
65 64
            FUNCTION_CURRENT_ROW,
......
75 74
        return feature;
76 75
      }
77 76
    };
78
    this.storeAdapter = new DynObjectAdapter() {
79
        @Override
80
        public Object getDynValue(String name) throws DynFieldNotFoundException {
81
          try {
82
            return feature.get(name);
83
          } catch (Exception ex) {
84
            return feature.getExtraValue(name);
85
          }
77
    this.storeAttributeHandler = new TableAttributeHandler() {
78
      @Override
79
      public Object get(String name) {
80
        try {
81
          return feature.get(name);
82
        } catch (Exception ex) {
83
          return feature.getExtraValue(name);
86 84
        }
85
      }
87 86

  
88
        @Override
89
        public boolean hasDynValue(String name) {
90
          if( feature.getType().get(name)!=null ) {
91
            return true;
92
          }
93
          return feature.hasExtraValue(name);
94
        }
95
        
96
      };
87
      @Override
88
      public String getName() {
89
        return storeName;
90
      }
91
    };
97 92
  }
98 93

  
99 94
  @Override
......
115 110
    if (type == null) {
116 111
      return false;
117 112
    }
118
    if ( type.get(name) != null) {
113
    if (type.get(name) != null) {
119 114
      return true;
120 115
    }
121
    if (StringUtils.equalsIgnoreCase(name, this.storeName)) {
116
    if (StringUtils.equalsIgnoreCase(name, this.storeName) ||
117
        StringUtils.equalsIgnoreCase(name, SYMBOL_CURRENT_TABLE) ||
118
        StringUtils.equalsIgnoreCase(name, SYMBOL_CURRENT_ROW) ) {
122 119
      return true;
123 120
    }
124
    if( feature==null ) {
121
    if (feature == null) {
125 122
      return false;
126 123
    }
127 124
    if (this.feature.hasExtraValue(name)) {
......
135 132
    if (feature == null) {
136 133
      return null;
137 134
    }
138
    if (StringUtils.equalsIgnoreCase(name, this.storeName)) {
139
      return this.storeAdapter;
135
    if (StringUtils.equalsIgnoreCase(name, this.storeName) ||
136
        StringUtils.equalsIgnoreCase(name, SYMBOL_CURRENT_TABLE)) {
137
      return this.storeAttributeHandler;
140 138
    }
139
    if (StringUtils.equalsIgnoreCase(name, SYMBOL_CURRENT_ROW)) {
140
      return this.feature;
141
    }
141 142
    try {
142 143
      return this.feature.get(name);
143 144
    } catch (Exception ex) {
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/ExistsFunction.java
60 60
              "list - a list of values or null"
61 61
            },
62 62
            "Boolean",
63
            false
63
            true
64 64
    );
65 65
  }
66 66

  
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;
26 27
import java.util.List;
27 28
import java.util.Objects;
28 29
import org.apache.commons.lang3.Range;
30
import org.apache.commons.lang3.StringUtils;
31
import org.apache.commons.lang3.tuple.ImmutablePair;
32
import org.apache.commons.lang3.tuple.Pair;
33
import org.gvsig.expressionevaluator.Code;
34
import org.gvsig.expressionevaluator.Code.Caller;
35
import org.gvsig.expressionevaluator.CodeBuilder;
29 36
import org.gvsig.expressionevaluator.Codes;
30
import org.gvsig.expressionevaluator.Expression;
37
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_GETATTR;
38
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_TUPLE;
31 39
import org.gvsig.expressionevaluator.ExpressionRuntimeException;
32 40
import org.gvsig.expressionevaluator.ExpressionUtils;
33 41
import org.gvsig.expressionevaluator.Interpreter;
42
import org.gvsig.expressionevaluator.Optimizer;
43
import org.gvsig.expressionevaluator.SymbolTable;
34 44
import org.gvsig.expressionevaluator.impl.DALFunctions;
35 45
import org.gvsig.expressionevaluator.spi.AbstractFunction;
36 46
import org.gvsig.fmap.dal.DALLocator;
37 47
import org.gvsig.fmap.dal.DataManager;
38 48
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT;
39 49
import org.gvsig.fmap.dal.DataStore;
50
import org.gvsig.fmap.dal.expressionevaluator.ExpressionEvaluator;
51
import static org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable.SYMBOL_CURRENT_TABLE;
52
import org.gvsig.fmap.dal.expressionevaluator.TableAttributeHandler;
40 53
import org.gvsig.fmap.dal.feature.Feature;
41 54
import org.gvsig.fmap.dal.feature.FeatureQuery;
42 55
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
43 56
import org.gvsig.fmap.dal.feature.FeatureStore;
57
import org.gvsig.fmap.dal.impl.expressionevaluator.DefaultExpressionEvaluator;
58
import org.gvsig.tools.exception.BaseException;
44 59

  
45 60
/**
46 61
 *
47 62
 * @author jjdelcerro
48 63
 */
49
public class SelectFunction extends AbstractFunction {
64
public class SelectFunction 
65
        extends AbstractFunction 
66
        implements Optimizer.FunctionOptimizer
67
  {
50 68

  
51 69
  public SelectFunction() {
52 70
    super(DALFunctions.GROUP_DATA_ACCESS,
53 71
            FUNCTION_SELECT,
54
            Range.between(1,5),
72
            Range.is(6),
55 73
            "Returns a list of features of the table by applying the filter, order and limit indicated.\n"+
56 74
                    "The syntax is:\n\n"+
57 75
                    "SELECT * FROM table WHERE boolean_expression ORDER BY order_column LIMIT limit;\n\n"+
......
65 83
              "limit - Maximum number of features to return"
66 84
            },
67 85
            "List",
68
            false
86
            true
69 87
    );
70 88
  }
71 89

  
......
80 98
  }
81 99

  
82 100
  @Override
83
  public boolean allowArgNames() {
84
    return true;
85
  }
86

  
87
  @Override
88 101
  public boolean useArgumentsInsteadObjects() {
89 102
    return true;
90 103
  }
......
94 107
    throw new UnsupportedOperationException();
95 108
  }
96 109

  
110
  private static final int COLUMNS = 0;
111
  private static final int TABLE = 1;
112
  private static final int WHERE = 2;
113
  private static final int ORDER = 3;
114
  private static final int ORDER_MODE = 4;
115
  private static final int LIMIT = 5;
116
  
117
  
118
  private Caller getTupleOrNull(Codes args, int argn) {
119
    Code code = args.get(argn);
120
    if( code.code()==Code.CONSTANT ) {
121
      if( ((Code.Constant)code).value()!=null ) {
122
        throw new ExpressionRuntimeException("Tupple or null expected in argument "+argn+ " of function '" + FUNCTION_SELECT + "'.");
123
      }
124
      return null;
125
    }
126
    if( code.code()!=Code.CALLER ) {
127
      throw new ExpressionRuntimeException("Tupple or null expected in argument "+argn+ " of function '" + FUNCTION_SELECT + "'.");
128
    }
129
    Caller caller = (Caller) code;
130
    if( !StringUtils.equalsIgnoreCase(FUNCTION_TUPLE, caller.name()) ) {
131
      throw new ExpressionRuntimeException("Tupple or null expected in argument "+argn+ " of function '" + FUNCTION_SELECT + "'.");
132
    }
133
    return caller;
134
  }
135
  
97 136
  @Override
98 137
  public Object call(Interpreter interpreter, Codes args) throws Exception {
99 138

  
100
    String storeName =  (String) getObject(interpreter, args, "TABLE");
101
    String where = Objects.toString(args.get("WHERE"),null);
102
    Number limit = (Number) getObject(interpreter, args, "LIMIT");
103
    FeatureQueryOrder order = null;
104
    for( int n=0 ; args.contains("ORDER", n); n++) {
105
      String member = (String) getObject(interpreter, args, "ORDER", n);
106
      Boolean mode = (Boolean) getObject(interpreter, args, "ORDER_MODE", n);
107
      if( order == null ) {
108
        order = new FeatureQueryOrder();
139
    Code.Identifier storeName =  (Code.Identifier) args.get(TABLE);
140
    Code columns = getTupleOrNull(args, COLUMNS);
141
    Code where = args.get(WHERE);
142
    Number limit = (Number) getObject(interpreter, args, LIMIT);
143
    Caller order = getTupleOrNull(args, ORDER);
144
    Caller order_mode = getTupleOrNull(args, ORDER_MODE);
145
    
146
    FeatureQueryOrder queryOrder = null;
147
    if( order!=null || order_mode!=null ) {
148
      for( int n=0 ; n<order.parameters().size(); n++) {
149
        String member = (String) interpreter.run(order.parameters().get(n));
150
        Boolean mode = (Boolean) interpreter.run(order_mode.parameters().get(n));
151
        if( queryOrder == null ) {
152
          queryOrder = new FeatureQueryOrder();
153
        }
154
        queryOrder.add(member, mode);
109 155
      }
110
      order.add(member, mode);
111 156
    }
112
    
157
    // FIXME: add columns to query.addAttributeName() 
113 158
    try {
114
      DataStore store = this.getStore(storeName);
159
      DataStore store = this.getStore(storeName.name());
115 160
      if (store == null ) {
116 161
        throw new ExpressionRuntimeException("Cant locate the store '" + storeName + "' in function '" + FUNCTION_SELECT + "'.");
117 162
      }
......
120 165
      }
121 166
      FeatureStore featureStore = (FeatureStore) store;
122 167
      List<Feature> features;
123
      if (where == null && order == null && limit==null ) {
168
      if (where == null && queryOrder == null && limit==null ) {
124 169
        features = featureStore.getFeatures();
125 170
      } else {
126 171
        FeatureQuery query = featureStore.createFeatureQuery();
127 172
        if (where != null) {
128
          Expression filter = ExpressionUtils.createExpression(where);
173
          removeOuterTablesReferences(interpreter, where);
174
          ExpressionEvaluator filter = new DefaultExpressionEvaluator(where.toString());
129 175
          filter.getSymbolTable().addSymbolTable(interpreter.getSymbolTable());
130 176
          query.addFilter(filter);
131 177
        }
132
        if (order != null) {
133
          query.getOrder().copyFrom(order);
178
        if (queryOrder != null) {
179
          query.getOrder().copyFrom(queryOrder);
134 180
        }
135 181
        if( limit!=null ) {
136 182
          query.setLimit(limit.longValue());
......
152 198
    return store;
153 199
  }
154 200

  
201
  private void removeOuterTablesReferences(Interpreter interpreter, Code where) {
202
    try {
203
      SymbolTable symbolTable = interpreter.getSymbolTable();
204
      TableAttributeHandler table = (TableAttributeHandler) symbolTable.value(SYMBOL_CURRENT_TABLE);
205
      List<Pair<Code,Code>>replaces = new ArrayList<>();
206
      CodeBuilder codeBuilder = ExpressionUtils.createCodeBuilder();
207
      where.accept((Object o) -> {
208
        Code code = (Code) o;
209
        if( code!=null && code.code() == Code.CALLER ) {
210
          Code.Caller caller = (Code.Caller) code;
211
          if( StringUtils.equalsIgnoreCase(caller.name(),FUNCTION_GETATTR) ) {
212
            Codes args = caller.parameters();
213
            Code arg0 = args.get(0);
214
            Code arg1 = args.get(1);
215
            if( arg0 instanceof Code.Identifier && arg1 instanceof Code.Identifier ) {
216
              Object tt = symbolTable.value(((Code.Identifier)arg0).name());
217
              if( tt instanceof TableAttributeHandler && 
218
                  StringUtils.equalsIgnoreCase(((TableAttributeHandler)tt).getName(), table.getName()) ) {
219
                String columnName = Objects.toString(((Code.Identifier)arg1).name(), null);
220
                if( columnName!=null ) {
221
                  Object value = table.get(columnName);
222
                  replaces.add(
223
                          new ImmutablePair<>(
224
                                  caller,
225
                                  codeBuilder.constant(value)
226
                          )
227
                  );
228
                }
229
              }
230
            }
231
          }
232
        }
233
      });
234
      for (Pair<Code, Code> replace : replaces) {
235
        if( replace!=null ) {
236
          where.replace(replace.getLeft(), replace.getRight());
237
        }
238
      }
239
    } catch (BaseException ex) {
240
      throw new ExpressionRuntimeException("Can't remove references to outer tables.", ex);
241
    }
242
                
243
  }
244

  
245
  @Override
246
  public Code optimize(Optimizer optimizer, Caller caller) {
247
    return caller; // Don't optimize SELECT
248
  }
249

  
155 250
}
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/SelectCountFunction.java
32 32
import org.gvsig.expressionevaluator.spi.AbstractFunction;
33 33
import org.gvsig.fmap.dal.DALLocator;
34 34
import org.gvsig.fmap.dal.DataManager;
35
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT;
36 35
import static org.gvsig.fmap.dal.DataManager.FUNCTION_SELECT_COUNT;
37 36
import org.gvsig.fmap.dal.DataStore;
38 37
import org.gvsig.fmap.dal.feature.FeatureQuery;
......
77 76
  }
78 77

  
79 78
  @Override
80
  public boolean allowArgNames() {
81
    return true;
82
  }
83

  
84
  @Override
85 79
  public boolean useArgumentsInsteadObjects() {
86 80
    return true;
87 81
  }
......
94 88
  @Override
95 89
  public Object call(Interpreter interpreter, Codes args) throws Exception {
96 90

  
97
    String storeName =  (String) getObject(interpreter, args, "TABLE");
98
    String where = Objects.toString(args.get("WHERE"),null);
91
    String storeName =  (String) getObject(interpreter, args, 0);
92
    String where = Objects.toString(args.get(1),null);
99 93
    
100 94
    FeatureStore featureStore = null;
101 95
    FeatureSet set = null;
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
24 24
package org.gvsig.expressionevaluator.impl.grammars;
25 25

  
26 26
import java.util.UUID;
27
import org.apache.commons.lang3.StringUtils;
27 28
import org.gvsig.expressionevaluator.Code;
28 29
import org.gvsig.expressionevaluator.Code.Caller;
29 30
import org.gvsig.expressionevaluator.CodeBuilder;
31
import org.gvsig.expressionevaluator.Codes;
30 32
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
31 33
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
34
import org.gvsig.expressionevaluator.ExpressionSyntaxException;
32 35
import org.gvsig.expressionevaluator.Grammar;
33 36
import org.gvsig.expressionevaluator.Statement;
37
import org.gvsig.expressionevaluator.Statement.ArgsBuilder;
34 38
import org.gvsig.expressionevaluator.Statement.StatementContext;
35 39
import org.gvsig.expressionevaluator.impl.DALFunctions;
36 40
import org.gvsig.expressionevaluator.impl.DefaultCodeBuilder.BaseCodes;
......
48 52
 */
49 53
public class DataAccessGrammarFactory extends AbstractGrammarFactory {
50 54

  
51
    private Grammar grammar;
55
  private Grammar grammar;
52 56

  
53
    private class ExistsStatementBuilder extends DefaultStatement.StatementBuilderBase {
57
  private static class ExistsStatementBuilder extends DefaultStatement.StatementBuilderBase {
54 58

  
55
        private final String listID;
56
        private final String existsID;
59
    private final String listID;
60
    private final String existsID;
57 61

  
58
        public ExistsStatementBuilder(String listID, String existsID) {
59
            super(ExistsFunction.NAME, new ArgsBuilderFromNames(listID,existsID));
60
            this.listID = listID;
61
            this.existsID = existsID;
62
        }
62
    public ExistsStatementBuilder(String listID, String existsID) {
63
      super(ExistsFunction.NAME, new ArgsBuilderFromNames(listID, existsID));
64
      this.listID = listID;
65
      this.existsID = existsID;
66
    }
63 67

  
64
        @Override
65
        public Code build(StatementContext context) {
68
    @Override
69
    public Code build(StatementContext context) {
66 70

  
67
            CodeBuilder codeBuilder = context.getCodeBuilder();
68
            Caller code = (Caller) super.build(context);
69
            BaseCodes args = (BaseCodes) code.parameters();
70
            if( args.size()<2 || args.get("ID")==null  ) {
71
              String exists_id = "EXISTS"+UUID.randomUUID().toString().replaceAll("-", "");
72
              args.add("ID", codeBuilder.constant(exists_id));
73
            }
74
            code = codeBuilder.function(ExistsFunction.NAME, args);
75
            return code;
76
        }
77
        
71
      CodeBuilder codeBuilder = context.getCodeBuilder();
72
      Caller code = (Caller) super.build(context);
73
      BaseCodes args = (BaseCodes) code.parameters();
74
      if (args.size() < 2) {
75
        String exists_id = "EXISTS" + UUID.randomUUID().toString().replaceAll("-", "");
76
        args.add(codeBuilder.constant(exists_id));
77
      } else if (args.get(1) == null) {
78
        String exists_id = "EXISTS" + UUID.randomUUID().toString().replaceAll("-", "");
79
        args.set(1, codeBuilder.constant(exists_id));
80
      }
81
      code = codeBuilder.function(ExistsFunction.NAME, args);
82
      return code;
78 83
    }
79 84

  
80
    public DataAccessGrammarFactory() {
81
        super(DALFunctions.GRAMMAR_NAME, true);
85
  }
86

  
87
  private static class SelectArgsBuilder implements ArgsBuilder {
88

  
89
    public SelectArgsBuilder() {
82 90
    }
83
    
91

  
84 92
    @Override
85
    public Grammar create(Object... parameters) {
86
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
87
        if( this.grammar==null ) {
88
            Grammar theGrammar = manager.createGrammar(this.getName());
89
            Statement stmt;
90
        
91
            theGrammar.addReservedWord("EXISTS");
92
            theGrammar.addReservedWord("SELECT");
93
            theGrammar.addReservedWord("FROM");
94
            theGrammar.addReservedWord("WHERE");
95
            theGrammar.addReservedWord("ORDER");
96
            theGrammar.addReservedWord("DESC");
97
            theGrammar.addReservedWord("ASC");
98
            theGrammar.addReservedWord("BY");
99
            
100
            stmt = theGrammar.createStatement("EXISTS");
101
            stmt.addRule(stmt.require_any_token("EXISTS"));
102
            stmt.addRule(stmt.require_any_token("("));
103
            stmt.addRule(stmt.require_expression("LIST"));
104
            stmt.addRule(stmt.optional_any_token(",")
105
                    .addRuleOnTrue(stmt.require_expression("ID"))
106
            );
107
            stmt.addRule(stmt.require_any_token(")"));
108
            stmt.builder(new ExistsStatementBuilder("LIST","ID"));
109
            theGrammar.addStatement(stmt);
93
    public String toString() {
94
      return "select_args()";
95
    }
110 96

  
111
            stmt = theGrammar.createStatement("FOREING_VALUE");
112
            stmt.addRule(stmt.require_any_token("FOREING"));
113
            stmt.addRule(stmt.require_any_token("VALUE"));
114
            stmt.addRule(stmt.require_any_token("FROM"));
115
            stmt.addRule(stmt.require_identifiers("IDENTIFIERS","."));
116
            stmt.code(
117
                    FUNCTION_FOREING_VALUE,
118
                    stmt.args_names("IDENTIFIERS")
119
            ); 
120
            theGrammar.addStatement(stmt);
97
    @Override
98
    public Codes build(StatementContext context) {
99
      context.trace(this.toString() + ".build");
100
      CodeBuilder codeBuilder = context.getCodeBuilder();
101
      BaseCodes args = (BaseCodes) codeBuilder.args();
121 102

  
122
            stmt = theGrammar.createStatement("SELECT");
123
            stmt.addRule(stmt.require_any_token("SELECT"));
124
            stmt.addRule(stmt.require_any_token("*","1"));
125
            stmt.addRule(stmt.require_any_token("FROM"));
126
            stmt.addRule(stmt.require_identifier("TABLE"));
127
            stmt.addRule(stmt.optional_any_token("WHERE")
128
                    .addRuleOnTrue(stmt.require_expression("WHERE"))
129
            );
130
            
131
            stmt.addRule(stmt.optional_any_token("ORDER")
132
                    .addRuleOnTrue(stmt.require_any_token("BY"))
133
                    .addRuleOnTrue(
134
                      stmt.repeat()
135
                          .addRule(stmt.require_expression("ORDER#"))
136
                          .addRule(stmt.switch_token()
137
                                  .addCase("ASC", 
138
                                          stmt.set_expression("ORDER_MODE#", true)
139
                                  )
140
                                  .addCase("DESC", 
141
                                          stmt.set_expression("ORDER_MODE#", false)
142
                                  )
143
                                  .addDefault(
144
                                          stmt.set_expression("ORDER_MODE#", true)
145
                                  )
146
                          )
147
                          .addRule(
148
                              stmt.optional_any_token(",")
149
                                  .addRuleOnFalse(stmt.break_loop())
150
                          )
151
                    )
152
            );    
153
            stmt.addRule(stmt.optional_any_token("LIMIT")
154
                    .addRuleOnTrue(stmt.require_expression("LIMIT"))
155
            );
156
            stmt.addRule(stmt.require_any_token(";"));
157
            stmt.code(
158
                    FUNCTION_SELECT,
159
                    stmt.args_names("TABLE","WHERE","ORDER#","ORDER_MODE#","LIMIT")
160
            ); 
161
            theGrammar.addStatement(stmt);
103
      Code columns = context.getCode("COLUMNS");
104
      Code table = context.getCode("TABLE");
105
      Code where = context.getCode("WHERE");
106
//      Code order = context.getCode("ORDER");
107
//      Code order_mode = context.getCode("ORDER_MODE");
108
      Code limit = context.getCode("LIMIT");
162 109

  
163
            stmt = theGrammar.createStatement("SELECT_COUNT");
164
            stmt.addRule(stmt.require_any_token("SELECT"));
165
            stmt.addRule(stmt.require_any_token("COUNT"));
166
            stmt.addRule(stmt.require_any_token("("));
167
            stmt.addRule(stmt.require_any_token("*"));
168
            stmt.addRule(stmt.require_any_token(")"));
169
            stmt.addRule(stmt.require_any_token("FROM"));
170
            stmt.addRule(stmt.require_identifier("TABLE"));
171
            stmt.addRule(stmt.optional_any_token("WHERE")
172
                    .addRuleOnTrue(stmt.require_expression("WHERE"))
173
            );
174
            stmt.addRule(stmt.require_any_token(";"));
175
            stmt.code(
176
                    FUNCTION_SELECT_COUNT,
177
                    stmt.args_names("TABLE","WHERE")
178
            ); 
179
            theGrammar.addStatement(stmt);
110
      if (columns == null) {
111
        throw new ExpressionSyntaxException();
112
      }
113
      Caller tuple = codeBuilder.tuple();
114
      args.add(tuple);
115
      String s = (String) ((Code.Constant) columns).value();
116
      if (!StringUtils.equalsIgnoreCase(s, "*")) {
117
        ((BaseCodes) (tuple.parameters())).add(codeBuilder.constant(1));
118
      }
119
      
120
      args.add(codeBuilder.identifier((String) ((Code.Constant) table).value()));
180 121

  
181
            this.grammar = theGrammar;
122
      if (where == null) {
123
        args.add(codeBuilder.constant(null));
124
      } else {
125
        args.add(where);
126
      }
127

  
128
      int n = 1;
129
      BaseCodes argsX = (BaseCodes) codeBuilder.args();
130
      while (true) {
131
        String argNameX = "ORDER" + String.valueOf(n);
132
        Code code = context.getCode(argNameX);
133
        if (code == null) {
134
          break;
182 135
        }
183
        return grammar;
136
        argsX.add(code);
137
        n++;
138
      }
139
      args.add(codeBuilder.tuple(argsX));
140

  
141
      n = 1;
142
      argsX = (BaseCodes) codeBuilder.args();
143
      while (true) {
144
        String argNameX = "ORDER_MODE" + String.valueOf(n);
145
        Code code = context.getCode(argNameX);
146
        if (code == null) {
147
          break;
148
        }
149
        argsX.add(code);
150
        n++;
151
      }
152
      args.add(codeBuilder.tuple(argsX));
153

  
154
      if (limit == null) {
155
        args.add(codeBuilder.constant(null));
156
      } else {
157
        args.add(limit);
158
      }
159
      return args;
160

  
184 161
    }
185
 
186
    public static final void selfRegister() {
187
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
188
        manager.registerGrammar(new DataAccessGrammarFactory());
162

  
163
  }
164

  
165
  private static class SelectCountArgsBuilder implements ArgsBuilder {
166

  
167
    public SelectCountArgsBuilder() {
189 168
    }
169

  
170
    @Override
171
    public String toString() {
172
      return "select_count_args()";
173
    }
174

  
175
    @Override
176
    public Codes build(StatementContext context) {
177
      context.trace(this.toString() + ".build");
178
      CodeBuilder codeBuilder = context.getCodeBuilder();
179
      BaseCodes args = (BaseCodes) codeBuilder.args();
180

  
181
      Code table = context.getCode("table");
182
      Code where = context.getCode("where");
183

  
184
      args.add(codeBuilder.identifier((String) ((Code.Constant) table).value()));
185

  
186
      if (where == null) {
187
        args.add(codeBuilder.constant(null));
188
      } else {
189
        args.add(where);
190
      }
191
      return args;
192
    }
193

  
194
  }
195

  
196
  public DataAccessGrammarFactory() {
197
    super(DALFunctions.GRAMMAR_NAME, true);
198
  }
199

  
200
  @Override
201
  public Grammar create(Object... parameters) {
202
    ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
203
    if (this.grammar == null) {
204
      Grammar theGrammar = manager.createGrammar(this.getName());
205
      Statement stmt;
206

  
207
      theGrammar.addReservedWord("EXISTS");
208
      theGrammar.addReservedWord("SELECT");
209
      theGrammar.addReservedWord("FROM");
210
      theGrammar.addReservedWord("WHERE");
211
      theGrammar.addReservedWord("ORDER");
212
      theGrammar.addReservedWord("DESC");
213
      theGrammar.addReservedWord("ASC");
214
      theGrammar.addReservedWord("BY");
215

  
216
      stmt = theGrammar.createStatement("EXISTS");
217
      stmt.addRule(stmt.require_any_token("EXISTS"));
218
      stmt.addRule(stmt.require_any_token("("));
219
      stmt.addRule(stmt.require_expression().capture_as("LIST"));
220
      stmt.addRule(stmt.optional_any_token(",")
221
              .addRuleOnTrue(stmt.require_expression().capture_as("ID"))
222
      );
223
      stmt.addRule(stmt.require_any_token(")"));
224
      stmt.builder(new ExistsStatementBuilder("LIST", "ID"));
225
      theGrammar.addStatement(stmt);
226

  
227
      stmt = theGrammar.createStatement("FOREING_VALUE");
228
      stmt.addRule(stmt.require_any_token("FOREING"));
229
      stmt.addRule(stmt.require_any_token("VALUE"));
230
      stmt.addRule(stmt.require_any_token("FROM"));
231
      stmt.addRule(stmt.require_identifiers(".").capture_as("IDENTIFIERS"));
232
      stmt.code(
233
              FUNCTION_FOREING_VALUE,
234
              stmt.args_names("IDENTIFIERS")
235
      );
236
      theGrammar.addStatement(stmt);
237

  
238
      stmt = theGrammar.createStatement("SELECT");
239
      stmt.addRule(stmt.require_any_token("SELECT"));
240
      stmt.addRule(stmt.switch_token()
241
              .addCase("*", stmt.set_expression("COLUMNS", "*"))
242
              .addCase("1", stmt.set_expression("COLUMNS", "1"))
243
              .addDefault(stmt.fail())
244
      );
245
      stmt.addRule(stmt.require_any_token("FROM"));
246
      stmt.addRule(stmt.require_identifier().capture_as("TABLE"));
247
      stmt.addRule(stmt.optional_any_token("WHERE")
248
              .addRuleOnTrue(stmt.require_expression().capture_as("WHERE"))
249
      );
250

  
251
      stmt.addRule(stmt.optional_any_token("ORDER")
252
              .addRuleOnTrue(stmt.require_any_token("BY"))
253
              .addRuleOnTrue(stmt.repeat()
254
                      .addRule(stmt.require_expression().capture_as("ORDER#"))
255
                      .addRule(stmt.switch_token()
256
                              .addCase("ASC", stmt.set_expression("ORDER_MODE#", true))
257
                              .addCase("DESC", stmt.set_expression("ORDER_MODE#", false))
258
                              .addDefault(stmt.set_expression("ORDER_MODE#", true))
259
                      )
260
                      .addRule(stmt.optional_any_token(",")
261
                              .addRuleOnFalse(stmt.break_loop())
262
                      )
263
              )
264
      );
265
      stmt.addRule(stmt.optional_any_token("LIMIT")
266
              .addRuleOnTrue(stmt.require_expression().capture_as("LIMIT"))
267
      );
268
      stmt.addRule(stmt.optional_any_token(";"));
269
      stmt.code(
270
              FUNCTION_SELECT,
271
              new SelectArgsBuilder()
272
      );
273
      theGrammar.addStatement(stmt);
274

  
275
      stmt = theGrammar.createStatement("SELECT_COUNT");
276
      stmt.addRule(stmt.require_any_token("SELECT"));
277
      stmt.addRule(stmt.require_any_token("COUNT"));
278
      stmt.addRule(stmt.require_any_token("("));
279
      stmt.addRule(stmt.require_any_token("*"));
280
      stmt.addRule(stmt.require_any_token(")"));
281
      stmt.addRule(stmt.require_any_token("FROM"));
282
      stmt.addRule(stmt.require_identifier().capture_as("TABLE"));
283
      stmt.addRule(stmt.optional_any_token("WHERE")
284
              .addRuleOnTrue(stmt.require_expression().capture_as("WHERE"))
285
      );
286
      stmt.addRule(stmt.require_any_token(";"));
287
      stmt.code(
288
              FUNCTION_SELECT_COUNT,
289
              new SelectCountArgsBuilder()
290
      );
291
      theGrammar.addStatement(stmt);
292

  
293
      this.grammar = theGrammar;
294
    }
295
    return grammar;
296
  }
297

  
298
  public static final void selfRegister() {
299
    ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
300
    manager.registerGrammar(new DataAccessGrammarFactory());
301
  }
190 302
}
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.impl/src/main/java/org/gvsig/fmap/dal/impl/expressionevaluator/DefaultExpressionEvaluator.java
93 93

  
94 94
    public DefaultExpressionEvaluator(Expression expression) {
95 95
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
96
        this.expression = expression;
97 96
        this.symbolTable = manager.createSymbolTable();
98
        this.featureSymbolTable = new FeatureSymbolTableImpl(
99
//                expression.getUserScript(), 
100
//                expression.getScripts()
101
        );
97
        this.featureSymbolTable = new FeatureSymbolTableImpl();
102 98
        this.symbolTable.addSymbolTable(this.featureSymbolTable);
103 99

  
100
        this.expression = expression;
104 101
    }
105 102

  
106 103
    @Override
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.impl/src/main/java/org/gvsig/fmap/dal/impl/expressionevaluator/DefaultFeatureAttributeEmulatorExpression.java
11 11
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
12 12
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
13 13
import org.gvsig.expressionevaluator.SymbolTable;
14
import org.gvsig.expressionevaluator.impl.symboltable.FeatureSymbolTableImpl;
14 15
import org.gvsig.fmap.dal.DataManager;
15 16
import org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable;
16 17
import org.gvsig.fmap.dal.feature.FeatureType;
......
112 113

  
113 114
    @Override
114 115
    public SymbolTable getSymbolTable() {
115
        if (this.symbolTable == null) {
116
        if (this.symbolTable == null || this.featureSymbolTable==null ) {
116 117
            ExpressionEvaluatorManager expressionManager = ExpressionEvaluatorLocator.getManager();
117
            this.featureSymbolTable = (FeatureSymbolTable) expressionManager.getSymbolTable(DataManager.DAL_SYMBOL_TABLE_FEATURE
118
            );
118
            this.featureSymbolTable = new FeatureSymbolTableImpl();
119 119
            this.symbolTable = expressionManager.createSymbolTable();
120 120
            this.symbolTable.addSymbolTable(this.featureSymbolTable);
121 121
        }
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.impl/src/main/java/org/gvsig/fmap/dal/impl/DefaultDatabaseWorkspaceManager.java
5 5
import java.util.Collection;
6 6
import java.util.Collections;
7 7
import java.util.List;
8
import java.util.Map;
8 9
import java.util.Objects;
10
import org.apache.commons.collections4.map.LRUMap;
9 11
import org.gvsig.fmap.dal.DatabaseWorkspaceManager;
10 12
import org.apache.commons.lang3.StringUtils;
11 13
import org.apache.commons.lang3.mutable.Mutable;
......
41 43
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
42 44
import org.gvsig.tools.dynobject.DynClass;
43 45
import org.gvsig.tools.dynobject.DynField;
44
import org.gvsig.tools.exception.BaseException;
45 46
import org.gvsig.tools.resourcesstorage.FilesResourcesStorage;
46 47
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
48
import org.gvsig.tools.util.CachedValue;
47 49
import org.gvsig.tools.util.FileTools;
48 50
import org.gvsig.tools.util.HasAFile;
49
import org.gvsig.tools.visitor.VisitCanceledException;
50
import org.gvsig.tools.visitor.Visitor;
51 51
import org.slf4j.Logger;
52 52
import org.slf4j.LoggerFactory;
53 53

  
......
66 66
    private static final String CONFIG_NAME_BASEFOLDER = "BASEFOLDER";
67 67
    private static final String CONFIG_NAME_ALTERNATIVE_RESOURCES_PATH = "ALTERNATIVE_RESOURCES_PATH";
68 68
    
69
    private static abstract class CachedValue<T> {
69
    private class CachedConfigValue extends CachedValue<String> {
70 70

  
71
        protected T value = null;
72
        private long lastAccess = 0;
73
        private final int millis;
74

  
75
        protected CachedValue(int millis) {
76
            this.millis = millis;
71
        private final String name;
72
      
73
        public CachedConfigValue(String name, String value) {
74
          this.setValue(value);
75
          this.name = name;
77 76
        }
78
        
79
        protected abstract void reload();
80

  
81
        public boolean isExpired() {
82
            long now = System.currentTimeMillis();
83
            return now - lastAccess > millis;
77
      
78
        public CachedConfigValue(String name, String value, long expireTime) {
79
          this.name = name;
80
          this.setValue(value);
81
          this.setExpireTime(expireTime);
84 82
        }
85

  
86
        public T get() {
87
            if (isExpired()) {
88
                reload();
89
            }
90
            lastAccess = System.currentTimeMillis();
91
            return value;
92
        }
93
        
94
        public void set(T value) {
95
            this.value = value;
96
            lastAccess = System.currentTimeMillis();
97
        }
98
    }
99

  
100
    private class BaseFolder extends CachedValue<File> {
101
        public BaseFolder() {
102
            super(3000);
103
        }
104

  
83
      
105 84
        @Override
106 85
        protected void reload() {
107
            String s = DefaultDatabaseWorkspaceManager.this.get(CONFIG_NAME_BASEFOLDER);
86
            String s = DefaultDatabaseWorkspaceManager.this.getConfigValue(name);
108 87
            if( StringUtils.isBlank(s) ) {
109
                this.value = null;
88
                this.setValue(null);
110 89
            } else {
111
                this.value = new File(s);
90
                this.setValue(s);
112 91
            }
113 92
        }
114

  
115
        @Override
116
        public void set(File value) {
117
            DefaultDatabaseWorkspaceManager.this.set(CONFIG_NAME_BASEFOLDER, value.toString());
118
            super.set(value);
119
        }
120 93
    }
121 94
    
122 95
    private final DataServerExplorerParameters serverParameters;
123 96
    private Boolean existsConfiguration = null;
124 97
    private StoresRepository storesRepository;
125 98
    private Mutable<File> alternativeResourcesFolder = null;
126
    private BaseFolder baseFolder = null;
99
    private CachedValue<File> baseFolder;
100
    private Map<String,CachedConfigValue> cachedConfigValues;
127 101
    
128 102
    public DefaultDatabaseWorkspaceManager(DataServerExplorerParameters serverParameters) {
129 103
        this.serverParameters = serverParameters;
130
        this.baseFolder = new BaseFolder();
104
        this.baseFolder = new CachedValue() {
105
          @Override
106
          protected void reload() {
107
            String s = DefaultDatabaseWorkspaceManager.this.getConfigValue(CONFIG_NAME_BASEFOLDER);
108
            if( StringUtils.isBlank(s) ) {
109
                this.setValue(null);
110
            } else {
111
                this.setValue(new File(s));
112
            }
113
          }
114
          
115
        };
116
        this.baseFolder.setExpireTime(20000); // 20seg
117
        this.cachedConfigValues = new LRUMap<>(20, 20);
131 118
    }
132 119

  
133 120
    @Override
......
337 324
            if( !this.existsConfiguration() ) {
338 325
                return null;
339 326
            }
327
            if( StringUtils.equalsIgnoreCase(name, CONFIG_NAME_BASEFOLDER) ) {
328
              return this.baseFolder.get().toString();
329
            }
330
            CachedConfigValue cachedValue = this.cachedConfigValues.get(name);
331
            if( cachedValue != null ) {
332
              return cachedValue.get();
333
            }
334
            String value = this.getConfigValue(name);
335
            this.cachedConfigValues.put(name, new CachedConfigValue(name, value, 15000));
336
            return value;
337
        } catch (Exception ex) {
338
            LOGGER.warn("Can't read configuration value '"+name+"'", ex);
339
            return null;
340
        }
341
    }
342
    
343
    private String getConfigValue(String name) {
344
        try {
345
            if( !this.existsConfiguration() ) {
346
                return null;
347
            }
340 348
            FeatureStore store = this.getTable(TABLE_CONFIGURATION);
341 349
            if( store == null ) {
342 350
                return null;
......
389 397
                store.update(efeature);
390 398
            }
391 399
            store.finishEditing();
400
            if( this.cachedConfigValues.containsKey(name) ) {
401
              this.cachedConfigValues.get(name).set(value);
402
            }
392 403
            return true;
393 404
        } catch (Exception ex) {
394 405
            LOGGER.warn("Can't write configuration value '"+name+"'", ex);
......
428 439
    @Override
429 440
    public void setBaseFolder(File baseFolder) {
430 441
        this.baseFolder.set(baseFolder);
442
        this.set(CONFIG_NAME_BASEFOLDER, baseFolder.toString());
431 443
    }
432 444

  
433 445
    private DataStoreParameters replaceInFilesToUseBaseFolder(DataStoreParameters parameters) {
......
595 607
    public boolean exists(String name) {
596 608
        try {
597 609
            if (this.existsConfiguration()) {
598
                FeatureStore store = this.getTable(TABLE_CONFIGURATION);
599
                if (store != null) {
600
                    ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
601
                    String filter = builder.eq(
602
                            builder.column(FIELD_CONFIGURATION_NAME),
603
                            builder.constant(name)
604
                    ).toString();
605
                    Feature feature = store.findFirst(filter);
606
                    if (feature != null) {
607
                        return true;
608
                    }
610
              if( StringUtils.equalsIgnoreCase(name, CONFIG_NAME_BASEFOLDER) ) {
611
                return true;
612
              }
613
              if( this.cachedConfigValues.containsKey(name) ) {
614
                return true;
615
              }
616
              FeatureStore store = this.getTable(TABLE_CONFIGURATION);
617
              if (store != null) {
618
                  ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
619
                  String filter = builder.eq(
620
                          builder.column(FIELD_CONFIGURATION_NAME),
621
                          builder.constant(name)
622
                  ).toString();
623
                  Feature feature = store.findFirst(filter);
624
                  if (feature != null) {
625
                      String value = feature.getString(FIELD_CONFIGURATION_VALUE);
626
                      value = ExpressionUtils.evaluateDynamicText(this, value);
627
                      this.cachedConfigValues.put(name, new CachedConfigValue(name, value, 15000));
628
                      return true;
629
                  }
609 630
                }
610 631
            }
611 632
            return super.exists(name);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff