Revision 44376

View differences:

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/feature/impl/DefaultFeatureType.java
392 392

  
393 393
            if (ArrayUtils.isEmpty(names)) {
394 394
                for (FeatureAttributeDescriptor attrdesc : parent) {
395
                    attrnames.add(attrdesc.getName());
395
                    attrnames.add(attrdesc.getName().toLowerCase());
396 396
                }
397
            } else {
397
            } else { 
398 398
                attrnames.addAll(Arrays.asList(names));
399 399
                requiredAttrnames.addAll(Arrays.asList(names));
400 400
            }
401 401
            // Add required fields for emulated fields
402 402
            if (parent.hasEmulators) {
403
                // Ojo, este bucle falla cuando hay un campo calculado que depende
404
                // de otro campo calculado.
403 405
                for (FeatureAttributeDescriptor attrdesc : parent) {
404 406
                    FeatureAttributeEmulator emulator = attrdesc.getFeatureAttributeEmulator();
405
                    if (emulator != null) {
406
                        String ss[] = emulator.getRequiredFieldNames();
407
                        if (ss != null) {
408
                            attrnames.addAll(Arrays.asList(ss));
409
                            requiredAttrnames.addAll(Arrays.asList(ss));
407
                    if (emulator != null && attrnames.contains(attrdesc.getName().toLowerCase())) {
408
                        String theNames[] = emulator.getRequiredFieldNames();
409
                        if (names != null) {
410
                            for (String name : theNames) {
411
                                name = name.toLowerCase();
412
                                attrnames.add(name);
413
                                requiredAttrnames.add(name);
414
                            }
410 415
                        }
411 416
                    }
412 417
                }
......
415 420
            if (includePk && !parent.hasOID()) {
416 421
                for (FeatureAttributeDescriptor attrdesc : parent) {
417 422
                    if (attrdesc.isPrimaryKey()) {
418
                        attrnames.add(attrdesc.getName());
419
                        requiredAttrnames.add(attrdesc.getName());
423
                        String name = attrdesc.getName().toLowerCase();
424
                        attrnames.add(name);
425
                        requiredAttrnames.add(name);
420 426
                    }
421 427
                }
422 428
            }
......
433 439
                attrcopy.index = i++;
434 440
            }
435 441

  
436
            // Set the consttants attributes.
442
            // Set the constants attributes.
437 443
            if (!ArrayUtils.isEmpty(constantsNames)) {
438 444
                for (String name : constantsNames) {
439 445
                    if (!requiredAttrnames.contains(name)) {
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/feature/impl/DefaultForeingKey.java
19 19
import org.gvsig.fmap.dal.feature.FeatureQuery;
20 20
import org.gvsig.fmap.dal.feature.FeatureStore;
21 21
import org.gvsig.fmap.dal.feature.FeatureType;
22
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
22 23
import org.gvsig.tools.ToolsLocator;
23 24
import org.gvsig.tools.dispose.DisposeUtils;
24 25
import org.gvsig.tools.dynobject.DynObjectValueItem;
......
394 395
            return null;
395 396
        }
396 397
        if( this.availableValues == null ) {
397
            context = createLocalContextIfNull(context);
398
            try {
399
                Expression labelExpression = context.getLabelExpression();
400
                FeatureStore store = context.getFeatureStore();
401
                if (store == null) {
402
                    return null;
403
                }
404
                int count = (int) store.getFeatureCount();
405
                DynObjectValueItem[] values = new DynObjectValueItem[Math.min(count, MAX_AVAILABLE_VALUES)];
406
                int n = 0;
407
                for (Feature feature : store.getFeatureSet()) {
408
                    Object code = feature.get(codeName);
409
                    Object value;
410
                    if (labelExpression == null) {
411
                        value = code;
412
                    } else {
413
                        context.getFeatureSymbolTable().setFeature(feature);
414
                        value = labelExpression.execute(context.getSymbolTable());
415
                    }
416
                    values[n++] = new DynObjectValueItem(code, Objects.toString(value, Objects.toString(code, "##ERROR##")));
417
                    if( n>=MAX_AVAILABLE_VALUES ) {
418
                        break;
419
                    }
420
                }
421
                this.availableValues = values;
422
            } catch (Exception ex) {
423
                LOGGER.warn("Can't get values from table '" + tableName + "' of field.", ex);
424
            } finally {
425
                disposeIfLocalContext(context);
398
            DataManagerProviderServices dataManager = (DataManagerProviderServices) DALLocator.getDataManager();
399
            FeatureStore myStore = this.descriptor.getStore();
400
            if( myStore!=null ) {
401
                this.availableValues = dataManager.getAvailableValues(myStore, this.descriptor);
426 402
            }
427 403
        }
428 404
        return this.availableValues;
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/feature/impl/DefaultFeature.java
1070 1070
        String label = attrdesc.getLabelOfValue(value);
1071 1071
        return label;
1072 1072
    }
1073
    
1073

  
1074
    @Override
1075
    public Object getExtraValue(String name) {
1076
        return this.data.getExtraValue(name);
1077
    }
1078

  
1079
    @Override
1080
    public Object getExtraValue(int index) {
1081
        return this.data.getExtraValue(index);
1082
    }
1083

  
1084

  
1074 1085
}
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/DefaultFeatureSymbolTable.java
3 3
import java.util.Arrays;
4 4
import java.util.List;
5 5
import org.apache.commons.lang3.Range;
6
import org.apache.commons.lang3.StringUtils;
6 7
import org.gvsig.expressionevaluator.ExpressionBuilder;
7 8
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
8 9
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
......
24 25
import org.gvsig.fmap.dal.feature.FeatureStore;
25 26
import org.gvsig.fmap.dal.feature.FeatureType;
26 27
import org.gvsig.fmap.dal.feature.ForeingKey;
27
import static org.gvsig.fmap.dal.impl.expressionevaluator.DALSymbolTable.FUNCTION_FEATURES;
28 28
import org.gvsig.fmap.dal.impl.expressionevaluator.DALSymbolTable.FeaturesFunction;
29
import org.gvsig.tools.dynobject.DynObjectAdapter;
30
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
29 31
import org.gvsig.tools.script.Script;
30 32
import org.gvsig.tools.util.UnmodifiableBasicList;
31 33
import org.gvsig.tools.util.UnmodifiableBasicListAdapter;
......
37 39
    @SuppressWarnings("UseSpecificCatch")
38 40
public class DefaultFeatureSymbolTable extends AbstractSymbolTable implements FeatureSymbolTable {
39 41

  
42
//    public static final String FUNCTION_FEATURES = "FEATURES";
43
//
44
//    public class FeaturesFunction extends AbstractFunction {
45
//
46
//        public FeaturesFunction() {
47
//            super(
48
//                    "Data access",
49
//                    FUNCTION_FEATURES,
50
//                    Range.between(1, 3),
51
//                    "Return a list of the features selecteds with filter in the store.",
52
//                    FUNCTION_FEATURES + "({{store_name}}, filter, order)",
53
//                    new String[]{
54
//                        "store - data store name to be used",
55
//                        "where - Optional. String value with a filter expression",
56
//                        "order - Optional. String value with the order. must be a string with the names of separate fields with commas"
57
//                    },
58
//                    "LIST"
59
//            );
60
//        }
61
//
62
//        @Override
63
//        public Object call(Interpreter interpreter, Object[] args) throws Exception {
64
//            String storeName = getStr(args, 0);
65
//            String where = null;
66
//            String order = null;
67
//            switch (args.length) {
68
//                case 2:
69
//                    where = getStr(args, 1);
70
//                    break;
71
//                case 3:
72
//                    where = getStr(args, 1);
73
//                    order = getStr(args, 2);
74
//                    break;
75
//            }
76
//            try {
77
//                DataStore store = getStore(storeName);
78
//                if (store == null || !(store instanceof FeatureStore)) {
79
//                    throw new ExpressionRuntimeException("Cant locate the store '" + storeName + "' in function '" + FUNCTION_FEATURES + "'.");
80
//                }
81
//                if (!(store instanceof FeatureStore)) {
82
//                    throw new ExpressionRuntimeException("The store'" + storeName + "' is not valid for function '" + FUNCTION_FEATURES + "', a FeatureStore is required.");
83
//                }
84
//                FeatureStore featureStore = (FeatureStore) store;
85
//                List<Feature> features;
86
//                if (where == null && order == null) {
87
//                    features = featureStore.getFeatures();
88
//                } else {
89
//                    FeatureQuery query = featureStore.createFeatureQuery();
90
//                    if (where != null) {
91
//                        query.addFilter(where);
92
//                    }
93
//                    if (order != null) {
94
//                        query.getOrder().add(order);
95
//                    }
96
//                    query.retrievesAllAttributes();
97
//                    features = featureStore.getFeatures(query);
98
//                }
99
//                return features;
100
//            } catch (ExpressionRuntimeException ex) {
101
//                throw ex;
102
//            } catch (Exception ex) {
103
//                throw new ExpressionRuntimeException("Problems calling '" + FUNCTION_FEATURES + "' function", ex);
104
//            }
105
//        }
106
//
107
//        protected DataStore getStore(String storeName) {
108
//            DataStore store = feature.getStore();
109
////            DataManager dataManager = DALLocator.getDataManager();
110
////            DataStore store = dataManager.getStoresRepository().getStore(storeName);
111
//            return store;
112
//        }
113
//    }
114

  
40 115
    public class ForeingValueFunction extends AbstractFunction {
41 116

  
42 117
        public ForeingValueFunction() {
......
66 141
                fieldNames = (UnmodifiableBasicList<String>) fields_o;
67 142
            } else {
68 143
                throw new ExpressionRuntimeException(
69
                    "Problems calling '" + FUNCTION_FEATURES + 
144
                    "Problems calling '" + FUNCTION_FOREING_VALUE + 
70 145
                    "' function, type of parameter '"+fields_o.getClass().getSimpleName()+
71 146
                    "' not supported, use string or list.");
72 147
            }
148
            
73 149
            Feature currentFeature = feature;
74 150
            try {
75 151
                String fieldName;
76 152
                Object value;
153
                
154
                value = feature.getExtraValue(StringUtils.join(fieldNames, "."));
155
                if( value != null ) {
156
                    return value;
157
                }
77 158
                for (int i = 0; i < fieldNames.size()-1; i++) {
78 159
                    fieldName = fieldNames.get(i);
79 160
                    value = currentFeature.get(fieldName);
......
93 174
            } catch (ExpressionRuntimeException ex) {
94 175
                throw ex;
95 176
            } catch (Exception ex) {
96
                throw new ExpressionRuntimeException("Problems calling '" + FUNCTION_FEATURES + "' function", ex);
177
                throw new ExpressionRuntimeException("Problems calling '" + FUNCTION_FOREING_VALUE + "' function", ex);
97 178
            }
98 179
        }
99 180
        
......
111 192
            DataStore store = null;
112 193
            if (feature != null) {
113 194
                store = feature.getStore();
114
                store = store.getChildren().get(storeName);
195
                store = store.getStoresRepository().getStore(storeName);
115 196
            }
116 197
            if (store == null) {
117 198
                StoresRepository repository = dataManager.getStoresRepository();
......
199 280

  
200 281
    private Feature feature;
201 282
    private FeatureType type;
283
    private String storeName;
202 284

  
203 285
    @SuppressWarnings("OverridableMethodCallInConstructor")
204 286
    public DefaultFeatureSymbolTable() {
205 287
        super(DataManager.DAL_SYMBOL_TABLE_FEATURE);
206 288

  
289

  
290
//        this.addFunction(new FeaturesFunction());
207 291
        this.addFunction(new FeatureFunction());
208 292
        this.addFunction(new FeatureStoreFunction());
209 293
        this.addFunction(new IsSelectedFunction());
......
243 327
        if (feature == null) {
244 328
            return null;
245 329
        }
330
        if( StringUtils.equalsIgnoreCase(name, this.storeName) ) {
331
            return new DynObjectAdapter() {
332
                @Override
333
                public Object getDynValue(String string) throws DynFieldNotFoundException {
334
                    return feature.get(string);
335
                }
336
            };
337
        }
246 338
        return this.feature.get(name);
247 339
    }
248 340

  
......
264 356
    @Override
265 357
    public void setFeature(Feature feature) {
266 358
        this.feature = feature;
267
        this.type = feature.getType();
359
        if( this.type == null ) {
360
            this.type = feature.getType();
361
            FeatureStore store = feature.getStore();
362
            if( store!=null ) {
363
                this.storeName = store.getName();
364
            }
365
        }
268 366
    }
269 367

  
270 368
    @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/DefaultDataManager.java
10 10
import java.util.HashMap;
11 11
import java.util.List;
12 12
import java.util.Map;
13
import java.util.Objects;
13 14
import org.apache.commons.io.IOUtils;
14 15
import org.apache.commons.lang3.StringUtils;
15 16
import org.gvsig.expressionevaluator.Expression;
16 17
import org.gvsig.expressionevaluator.ExpressionBuilder;
17 18
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
19
import org.gvsig.expressionevaluator.MutableSymbolTable;
18 20
import org.gvsig.fmap.dal.BaseStoresRepository;
21
import org.gvsig.fmap.dal.DALLocator;
19 22

  
20 23
import org.gvsig.fmap.dal.DataFactory;
21 24
import org.gvsig.fmap.dal.DataManager;
......
45 48
import org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable;
46 49
import org.gvsig.fmap.dal.feature.DataProfile;
47 50
import org.gvsig.fmap.dal.feature.EditableFeatureType;
51
import org.gvsig.fmap.dal.feature.Feature;
48 52
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
49 53
import org.gvsig.fmap.dal.feature.FeatureQuery;
50 54
import org.gvsig.fmap.dal.feature.FeatureStore;
51 55
import org.gvsig.fmap.dal.feature.FeatureType;
56
import org.gvsig.fmap.dal.feature.ForeingKey;
57
import static org.gvsig.fmap.dal.feature.ForeingKey.MAX_AVAILABLE_VALUES;
52 58
import org.gvsig.fmap.dal.feature.impl.DALFile;
53 59
import org.gvsig.fmap.dal.feature.impl.DefaultEditableFeatureType;
54 60
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureIndex;
......
78 84
import org.gvsig.tools.dataTypes.DataType;
79 85
import org.gvsig.tools.dataTypes.DataTypesManager;
80 86
import org.gvsig.tools.dynobject.DynObject;
87
import org.gvsig.tools.dynobject.DynObjectValueItem;
81 88
import org.gvsig.tools.dynobject.DynStruct;
82 89
import org.gvsig.tools.dynobject.DynStruct_v2;
83 90
import org.gvsig.tools.dynobject.Tags;
......
1103 1110
            IOUtils.closeQuietly(resource);
1104 1111
        }
1105 1112
    }
1113

  
1114
    private Map<String,DynObjectValueItem[]> availableValues = null;
1115
    
1116
    @Override
1117
    public DynObjectValueItem[] getAvailableValues(FeatureStore myStore, FeatureAttributeDescriptor descriptor) {
1118
        String keyName = myStore.getFullName() + ":columnName=" + descriptor.getName();
1119
        if( this.availableValues==null ) {
1120
            this.availableValues = new HashMap<>();
1121
        }
1122
        DynObjectValueItem[] values = this.availableValues.get(keyName);
1123
        if( values != null ) {
1124
            return values;
1125
        }
1126
        if( !descriptor.isForeingKey() ) {
1127
            return null;
1128
        }
1129
        ForeingKey foreingKey = descriptor.getForeingKey();
1130
        try {
1131
            StoresRepository theStoresRepository;
1132
            FeatureStore store = descriptor.getStore();
1133
            if (store == null) {
1134
                theStoresRepository = DALLocator.getDataManager().getStoresRepository();
1135

  
1136
            } else {
1137
                theStoresRepository = store.getStoresRepository();
1138
            }
1139
            FeatureStore foreingStore = (FeatureStore) theStoresRepository.getStore(
1140
                foreingKey.getTableName()
1141
            );
1142
            Expression labelExpression = foreingKey.getLabelExpression(null);
1143
            String codeName = foreingKey.getCodeName();
1144
            FeatureSymbolTable featureSymbolTable = this.createFeatureSymbolTable();
1145
            MutableSymbolTable symbolTable = featureSymbolTable.createParent();
1146
        
1147
            int count = (int) foreingStore.getFeatureCount();
1148
            values = new DynObjectValueItem[Math.min(count, MAX_AVAILABLE_VALUES)];
1149
            int n = 0;
1150
            for (Feature feature : foreingStore.getFeatureSet()) {
1151
                Object code = feature.get(codeName);
1152
                Object value;
1153
                if (labelExpression == null) {
1154
                    value = code;
1155
                } else {
1156
                    featureSymbolTable.setFeature(feature);
1157
                    value = labelExpression.execute(symbolTable);
1158
                }
1159
                values[n++] = new DynObjectValueItem(code, Objects.toString(value, Objects.toString(code, "##ERROR##")));
1160
                if( n>=MAX_AVAILABLE_VALUES ) {
1161
                    break;
1162
                }
1163
            }
1164
            this.availableValues.put(keyName, values);
1165
            return values;
1166
        } catch (Exception ex) {
1167
            LOGGER.warn("Can't get available values for field '"+myStore.getName()+"."+descriptor.getName()+"' from table '" + foreingKey.getTableName() + "'.", ex);
1168
        }
1169
        return null;
1170
    }
1171

  
1106 1172
}
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/pom.xml
52 52
    <dependency>
53 53
        <groupId>org.gvsig</groupId>
54 54
        <artifactId>org.gvsig.fmap.dal.impl</artifactId>
55
        <type>test-jar</type>
56 55
        <scope>test</scope>
57 56
    </dependency>
58 57
    <dependency>
59 58
        <groupId>org.gvsig</groupId>
60
        <artifactId>org.gvsig.tools.lib</artifactId>
61
        <type>test-jar</type>
62
        <scope>test</scope>
63
    </dependency>    
64
    <dependency>
65
        <groupId>org.gvsig</groupId>
66 59
        <artifactId>${org.gvsig.fmap.geometry.impl}</artifactId>
67 60
        <scope>test</scope>
68 61
    </dependency>    
......
76 69
        <artifactId>${org.gvsig.proj.lib.impl}</artifactId>
77 70
        <scope>test</scope>
78 71
    </dependency>
72
    <dependency>
73
      <artifactId>junit</artifactId>
74
      <groupId>junit</groupId>
75
      <version>4.11</version>
76
    </dependency>
79 77
  </dependencies>
80 78

  
81 79

  
......
88 86
          <skipTests>true</skipTests>
89 87
        </configuration>
90 88
      </plugin>-->
91

  
89
<!--
92 90
      <plugin>
93 91
        <groupId>org.apache.maven.plugins</groupId>
94 92
        <artifactId>maven-compiler-plugin</artifactId>
......
105 103
          </execution>
106 104
        </executions>
107 105
      </plugin>
106
    -->
107
      <plugin>
108
        <groupId>org.apache.maven.plugins</groupId>
109
        <artifactId>maven-surefire-plugin</artifactId>
110
        <version>2.15</version>
111
      </plugin>
108 112
    </plugins>
109 113
  </build>
110 114

  
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/test/java/org/gvsig/fmap/dal/store/jdbc2/SQLBuilderTest.java
1 1
package org.gvsig.fmap.dal.store.jdbc2;
2 2

  
3
import java.util.List;
3 4
import junit.framework.TestCase;
4 5
import org.apache.commons.lang3.ArrayUtils;
5 6
import org.cresques.cts.IProjection;
6 7
import org.gvsig.expressionevaluator.ExpressionBuilder;
7 8
import org.gvsig.fmap.crs.CRSFactory;
9
import org.gvsig.fmap.dal.DALLocator;
10
import org.gvsig.fmap.dal.DataManager;
8 11
import org.gvsig.fmap.dal.SQLBuilder;
9 12
import org.gvsig.fmap.dal.SQLBuilder.Privilege;
13
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
14
import org.gvsig.fmap.dal.feature.EditableFeatureType;
15
import org.gvsig.fmap.dal.feature.EditableForeingKey;
10 16
import org.gvsig.fmap.dal.feature.spi.SQLBuilderBase;
17
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCHelperBase;
11 18
import org.gvsig.fmap.geom.DataTypes;
12 19
import org.gvsig.fmap.geom.Geometry;
13 20
import org.gvsig.fmap.geom.GeometryLocator;
......
76 83
        System.out.println("# Variables:: " + ArrayUtils.toString(sqlbuilder.variables_names()));
77 84
        System.out.println("# Parametros:: " + ArrayUtils.toString(sqlbuilder.parameters_names()));
78 85
        assertEquals(
79
                "SELECT ST_AsBinary(ST_ExtentAggregate(\"the_geom\")) AS \"envelope\" FROM \"master\".\"dbo\".\"test1\" WHERE ST_Intersects((ST_Envelope(\"the_geom\")), (ST_GeomFromWKB((DECODE('000000000300000001000000050000000000000000000000000000000000000000000000004059000000000000405900000000000040590000000000004059000000000000000000000000000000000000000000000000000000000000','hex')), (4326)))) AND x = 27",
86
                "SELECT ST_AsBinary(ST_ExtentAggregate(\"the_geom\")) AS \"envelope\" FROM \"master\".\"dbo\".\"test1\" WHERE (ST_Intersects((ST_Envelope(\"the_geom\")), (ST_GeomFromWKB((DECODE('000000000300000001000000050000000000000000000000000000000000000000000000004059000000000000405900000000000040590000000000004059000000000000000000000000000000000000000000000000000000000000','hex')), (4326)))) AND x = 27)",
80 87
                sqlbuilder.toString()
81 88
        );
82 89
        assertEquals(
......
294 301
            )
295 302
        );
296 303

  
297
        // DELETE FROM "master"."dbo"."test1" WHERE ( ("id1") = (?) ) AND ( ("id2") = (?) )
304
//        # Test:: testPerformDeletes
305
//        # SQL:: DELETE FROM "master"."dbo"."test1" WHERE (( ("id1") = (?) ) AND ( ("id2") = (?) ))
306
//        # Variables:: [id1, id2]
307
//        # Parametros:: ["id1", "id2"]
298 308

  
299 309
        System.out.println("# Test:: testPerformDeletes");
300 310
        System.out.println("# SQL:: " + sqlbuilder.toString());
301 311
        System.out.println("# Variables:: " + ArrayUtils.toString(sqlbuilder.variables_names()));
302 312
        System.out.println("# Parametros:: " + ArrayUtils.toString(sqlbuilder.parameters_names()));
303 313
        assertEquals(
304
                "DELETE FROM \"master\".\"dbo\".\"test1\" WHERE ( (\"id1\") = (?) ) AND ( (\"id2\") = (?) )",
314
                "DELETE FROM \"master\".\"dbo\".\"test1\" WHERE (( (\"id1\") = (?) ) AND ( (\"id2\") = (?) ))",
305 315
                sqlbuilder.toString()
306 316
        );
307 317
        assertEquals(
......
503 513
        );
504 514
    }
505 515

  
516
    public void testForeingValue() throws Exception {
517
        DataManager dataManager = DALLocator.getDataManager();
518
        JDBCHelperBase helper = new JDBCHelperBase(null);
519
        
520
        SQLBuilder sqlbuilder = createSQLBuilder();
521
        ExpressionBuilder expbuilder = sqlbuilder.expression();
522
        
523
        EditableFeatureAttributeDescriptor attr;
524
        EditableForeingKey foreingKey;
525
        EditableFeatureType ft = dataManager.createFeatureType();
526
        ft.add("ID", DataTypes.INT);
527
        ft.add("NAME", DataTypes.STRING, 80);
528
        attr = ft.add("TYPE", DataTypes.INT);
529
        foreingKey = attr.getForeingKey();
530
        foreingKey.setForeingKey(true);
531
        foreingKey.setClosedList(true);
532
        foreingKey.setCodeName("ID");
533
        foreingKey.setTableName("TYPES");
534
        attr = ft.add("PHONE_TYPE", DataTypes.INT);
535
        foreingKey = attr.getForeingKey();
536
        foreingKey.setForeingKey(true);
537
        foreingKey.setClosedList(true);
538
        foreingKey.setCodeName("ID");
539
        foreingKey.setTableName("PHONE_TYPES");
540
        
541
        
542
        sqlbuilder.select().column().name("ID");
543
        sqlbuilder.select().column().name("NAME");
544
        sqlbuilder.select().column().name("DESCRIPTION");
545
        sqlbuilder.select().column().name("TYPE");
546
        sqlbuilder.select().from().table().schema("dbo").name("test1");
547
        sqlbuilder.select().where().set( 
548
            expbuilder.and(
549
                expbuilder.like(
550
                    expbuilder.function(
551
                        "FOREING_VALUE",
552
                        expbuilder.constant("TYPE.DESCRIPTION")
553
                    ),
554
                    expbuilder.constant("A%")
555
                ),
556
                expbuilder.eq(
557
                    expbuilder.function(
558
                        "FOREING_VALUE",
559
                        expbuilder.constant("PHONE_TYPE.DESCRIPTION")
560
                    ),
561
                    expbuilder.constant("mobile")
562
                )
563
            )
564
        );
565
        System.out.println("# Test:: testForeingValue");
566
        System.out.println("# SQL1:: " + sqlbuilder.toString());        
506 567

  
568
        String[] attrNames = helper.replaceForeingValueFunction(sqlbuilder, ft);
569
        
570
        System.out.println("# SQL2:: " + sqlbuilder.toString());
571
        System.out.println("# Variables:: " + ArrayUtils.toString(sqlbuilder.variables_names()));
572
        System.out.println("# Parametros:: " + ArrayUtils.toString(sqlbuilder.parameters_names()));
573
        System.out.println("# attrNames:: " + ArrayUtils.toString(attrNames));
574

  
575
        //# Test:: testForeingValue
576
        //# SQL1:: SELECT "ID", "NAME", "DESCRIPTION", "TYPE" FROM "dbo"."test1" WHERE (( (FOREING_VALUE('TYPE.DESCRIPTION')) LIKE ('A%') ) AND ( (FOREING_VALUE('PHONE_TYPE.DESCRIPTION')) = ('mobile') ))
577
        //# SQL2:: SELECT "ID", "NAME", "dbo"."test1"."DESCRIPTION", "TYPE", "dbo"."TYPES"."DESCRIPTION", "dbo"."PHONE_TYPES"."DESCRIPTION" FROM "dbo"."test1" LEFT JOIN "dbo"."TYPES" ON ( ("dbo"."test1"."TYPE") = ("dbo"."TYPES"."ID") ) LEFT JOIN "dbo"."PHONE_TYPES" ON ( ("dbo"."test1"."PHONE_TYPE") = ("dbo"."PHONE_TYPES"."ID") ) WHERE (( ("dbo"."TYPES"."DESCRIPTION") LIKE ('A%') ) AND ( ("dbo"."PHONE_TYPES"."DESCRIPTION") = ('mobile') ))
578
        //# Variables:: [DESCRIPTION, DESCRIPTION, DESCRIPTION, ID, NAME, TYPE]
579
        //# Parametros:: []
580
        //# attrNames:: [TYPE.DESCRIPTION, PHONE_TYPE.DESCRIPTION]
581

  
582
        assertEquals(
583
                "SELECT \"ID\", \"NAME\", \"dbo\".\"test1\".\"DESCRIPTION\", \"TYPE\", \"dbo\".\"TYPES\".\"DESCRIPTION\", \"dbo\".\"PHONE_TYPES\".\"DESCRIPTION\" FROM \"dbo\".\"test1\" LEFT JOIN \"dbo\".\"TYPES\" ON ( (\"dbo\".\"test1\".\"TYPE\") = (\"dbo\".\"TYPES\".\"ID\") ) LEFT JOIN \"dbo\".\"PHONE_TYPES\" ON ( (\"dbo\".\"test1\".\"PHONE_TYPE\") = (\"dbo\".\"PHONE_TYPES\".\"ID\") ) WHERE (( (\"dbo\".\"TYPES\".\"DESCRIPTION\") LIKE ('A%') ) AND ( (\"dbo\".\"PHONE_TYPES\".\"DESCRIPTION\") = ('mobile') ))",
584
                sqlbuilder.toString()
585
        );
586
        assertEquals(
587
                "[DESCRIPTION, DESCRIPTION, DESCRIPTION, ID, NAME, TYPE]",
588
                ArrayUtils.toString(sqlbuilder.variables_names())
589
        );
590
        assertEquals(
591
                "[]",
592
                ArrayUtils.toString(sqlbuilder.parameters_names())
593
        );
594
        assertEquals(
595
                "{TYPE.DESCRIPTION,PHONE_TYPE.DESCRIPTION}",
596
                ArrayUtils.toString(attrNames)
597
        );
598
    }
599
    
600

  
507 601
}
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/OperationsFactory.java
68 68
    );
69 69

  
70 70
    public CalculateEnvelopeOfColumnOperation createCalculateEnvelopeOfColumn(
71
            FeatureType featureType,
71 72
            TableReference table,
72 73
            String columnName,
73 74
            String baseFilter,
......
90 91
    );
91 92

  
92 93
    public CountOperation createCount(
94
            FeatureType featureType,
93 95
            TableReference table,
94 96
            String baseFilter,
95 97
            String filter
96 98
    );
97 99

  
98 100
    public TableIsEmptyOperation createTableIsEmpty(
101
            FeatureType featureType,
99 102
            TableReference table,
100 103
            String baseFilter,
101 104
            String filtersql
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/spi/JDBCHelperBase.java
5 5
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.OperationsFactoryBase;
6 6
import java.sql.Connection;
7 7
import java.sql.ResultSet;
8
import java.util.ArrayList;
9
import java.util.List;
10
import org.apache.commons.lang3.ArrayUtils;
8 11
import org.apache.commons.lang3.StringUtils;
9 12
import org.apache.commons.lang3.mutable.MutableBoolean;
10 13
import org.gvsig.expressionevaluator.Code;
14
import org.gvsig.expressionevaluator.ExpressionBuilder;
11 15
import org.gvsig.expressionevaluator.ExpressionBuilder.GeometrySupportType;
12 16
import static org.gvsig.expressionevaluator.ExpressionBuilder.GeometrySupportType.EWKB;
13 17
import static org.gvsig.expressionevaluator.ExpressionBuilder.GeometrySupportType.NATIVE;
......
18 22
import org.gvsig.expressionevaluator.Function;
19 23
import org.gvsig.expressionevaluator.SymbolTable;
20 24
import org.gvsig.fmap.dal.DataTypes;
25
import org.gvsig.fmap.dal.SQLBuilder;
21 26
import org.gvsig.fmap.dal.exception.DataException;
22 27
import org.gvsig.fmap.dal.exception.InitializeException;
23 28
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
24 29
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
25 30
import org.gvsig.fmap.dal.feature.FeatureType;
31
import org.gvsig.fmap.dal.feature.ForeingKey;
26 32

  
27 33
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
34
import org.gvsig.fmap.dal.feature.spi.SQLBuilderBase;
28 35
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
29 36
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
30 37
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
......
160 167
        return QUOTE_FOR_USE_IN_STRINGS;
161 168
    }
162 169

  
170
    protected boolean supportCaller(Code.Caller caller) {
171
        if( StringUtils.equalsIgnoreCase(caller.name(), "FOREING_VALUE") ) {
172
            return true;
173
        }
174
        Function function = caller.function();
175
        if( function==null ) {
176
            return false;
177
        }
178
        if( !function.isSQLCompatible() ) {
179
            return false;
180
        }
181
        if( !this.hasSpatialFunctions() ) {
182
            if( StringUtils.equalsIgnoreCase(function.group(),Function.GROUP_OGC) ) {
183
                return false;
184
            }
185
        }
186
        return true;
187
    }
188
    
163 189
    @Override
164 190
    public boolean supportFilter(final FeatureType type, Evaluator filter) {
165 191
        // No podemos filtrar cuando:
......
194 220
        // proveedor dice que no soporta funciones espaciales.
195 221
        // Tambien comprobaremos que el filtro no usa ningun campo calculado.
196 222
        final MutableBoolean isCompatible = new MutableBoolean(true);
197
        final boolean supportSpatialFunctions = this.hasSpatialFunctions();
198 223
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
199 224
        Code code = manager.compile(sql);
200 225
        SymbolTable symbolTable = manager.createSymbolTable();
......
207 232
                    switch(code.code()) {
208 233
                        case Code.CALLER:
209 234
                            Code.Caller caller = (Code.Caller) code;
210
                            Function function = caller.function();
211
                            if( function==null ) {
235
                            if( !supportCaller(caller) ) {
212 236
                                isCompatible.setValue(false);
213 237
                                throw new VisitCanceledException();
214 238
                            }
215
                            if( !function.isSQLCompatible() ) {
216
                                isCompatible.setValue(false);
217
                                throw new VisitCanceledException();
218
                            }
219
                            if( !supportSpatialFunctions ) {
220
                                if( StringUtils.equalsIgnoreCase(function.group(),Function.GROUP_OGC) ) {
221
                                    isCompatible.setValue(false);
222
                                    throw new VisitCanceledException();
223
                                }
224
                            }
225 239
                            break;
226 240
                            
227 241
                        case Code.IDENTIFIER:
......
398 412

  
399 413
    @Override
400 414
    public void fetchFeature(FeatureProvider feature, ResultSetEntry rs) throws DataException {
401
        fetchFeature(feature, rs.get(), rs.getColumns());
415
        fetchFeature(feature, rs.get(), rs.getColumns(), rs.getExtraValueNames());
402 416
    }
403 417

  
404 418
    @Override
405
    public void fetchFeature(FeatureProvider feature, ResultSet rs, FeatureAttributeDescriptor[] columns) throws DataException {
419
    public void fetchFeature(FeatureProvider feature, ResultSet rs, FeatureAttributeDescriptor[] columns, String[] extraValueNames) throws DataException {
406 420
        Object value;
407
        FeatureAttributeDescriptor column;
408 421
        try {
409
            for (int index = 0; index < columns.length; index++) {
410
                column = columns[index];
422
            int rsIndex = 1;
423
            for (FeatureAttributeDescriptor column : columns) {
411 424
                switch (column.getType()) {
412 425
                    case DataTypes.GEOMETRY:
413
                        value = this.getGeometryFromColumn(rs, index + 1);
426
                        value = this.getGeometryFromColumn(rs, rsIndex++);
414 427
                        break;
415 428
                    default:
416
                        value = rs.getObject(index + 1);
429
                        value = rs.getObject(rsIndex++);
417 430
                        if( value instanceof Blob ) {
418 431
                            Blob blob = (Blob)value;
419 432
                            value = blob.getBytes(0, (int) blob.length());
......
422 435
                }
423 436
                feature.set(column.getIndex(), value);
424 437
            }
438
            if( ArrayUtils.isNotEmpty(extraValueNames) ) {
439
                feature.setExtraValueNames(extraValueNames);
440
                for (int index = 0; index < extraValueNames.length; index++) {
441
                    value = rs.getObject(rsIndex++);
442
                    if( value instanceof Blob ) {
443
                        Blob blob = (Blob)value;
444
                        value = blob.getBytes(0, (int) blob.length());
445
                        blob.free();
446
                    }
447
                    feature.setExtraValue(index, value);
448
                }
449
            }
425 450
        } catch (Exception ex) {
426 451
            throw new JDBCCantFetchValueException(ex);
427 452
        }
......
542 567
        return true;
543 568
    }
544 569
    
570
    @Override
571
    public String[] replaceForeingValueFunction(SQLBuilder sqlbuilder, FeatureType type) {
572
        // See test SQLBuilderTest->testForeingValue()
573
        final ExpressionBuilder where = sqlbuilder.select().where();
574
        if( where == null || where.isEmpty() ) {
575
            return null;
576
        }
577
        final SQLBuilder.TableNameBuilder table = sqlbuilder.select().from().table();
578
        final ExpressionBuilder expbuilder = sqlbuilder.expression();
579
        
580
        final List<String> foreing_value_args = new ArrayList<>();
581
        final List<ExpressionBuilder.Value[]> value_replacements = new ArrayList<>();
582

  
583
        // Buscamos las llamadas a la funcion "foreing_value" y nos quedamos
584
        // el argumento de esta asi como por que tendriamos que sustituirla 
585
        // una vez hechos los left joins que toquen.
586
        where.accept(new ExpressionBuilder.Visitor() {
587
            @Override
588
            public void visit(ExpressionBuilder.Visitable value) {
589
                // Requiere que sea la funcion "FOREING_VALUE con un solo 
590
                // argumento que sea una constante de tipo string.
591
                if( !(value instanceof ExpressionBuilder.Function) ) {
592
                    return;
593
                }
594
                ExpressionBuilder.Function function = (ExpressionBuilder.Function) value;
595
                if( !StringUtils.equalsIgnoreCase(function.name(), "FOREING_VALUE") ) {
596
                    return;
597
                }
598
                if( function.parameters().size()!=1 ) {
599
                    return;
600
                } 
601
                ExpressionBuilder.Value arg = function.parameters().get(0);
602
                if( !(arg instanceof ExpressionBuilder.Constant) ) {
603
                    return;
604
                }
605
                Object arg_value = ((ExpressionBuilder.Constant) arg).value();
606
                if( !(arg_value instanceof CharSequence) ) {
607
                    return;
608
                }
609
                String foreing_value_arg = arg_value.toString();
610
                String[] foreingNameParts = StringUtils.split(foreing_value_arg, "[.]");
611
                if( foreingNameParts.length!=2 ) {
612
                    // De momento solo tratamos joins entre dos tablas.
613
                    return;
614
                }
615
                String columnNameLocal = foreingNameParts[0];
616
                String columnNameForeing = foreingNameParts[1];
617
                FeatureAttributeDescriptor attr = type.getAttributeDescriptor(columnNameLocal);
618
                if( !attr.isForeingKey() ) {
619
                    // Uhm... si el argumento no referencia a un campo que es
620
                    // clave ajena no lo procesamos. 
621
                    // ? Deberiamos lanzar un error ?
622
                    return;
623
                }
624
                // Nos guardaremos por que hay que reemplazar la funcion 
625
                // FOREING_VALUE, y su argumento para mas tarde.
626
                ForeingKey foreingKey = attr.getForeingKey();
627
                SQLBuilder.TableNameBuilder foreingTable = sqlbuilder.createTableNameBuilder()
628
                        .database(table.getDatabase())
629
                        .schema(table.getSchema()) 
630
                        .name(foreingKey.getTableName());
631
                // Reemplzaremos la funcion FOREING_VALUE, por el acceso al campo
632
                // que toca de la tabla a la que referencia la clave ajena.
633
                ExpressionBuilder.Variable function_replacement = sqlbuilder.column(foreingTable, columnNameForeing);
634
                value_replacements.add(
635
                    new ExpressionBuilder.Value[] {
636
                        function,
637
                        function_replacement
638
                    }
639
                );
640
                foreing_value_args.add(foreing_value_arg);
641
            }
642
        }, null);
643
            
644
        // Si no habia ningun llamada a la funcion FOREING_VALUE, no hay que
645
        // hacer nada.
646
        if( foreing_value_args.isEmpty() ) {
647
            return null;
648
        }
649

  
650
        // Calculamos que referencias de columnas hemos de cambiar para 
651
        // que no aparezcan ambiguedades al hacer el join (nombres de
652
        // columna de una y otra tabla que coincidan).
653
        // Para las columnas que puedan dar conflicto se prepara un reemplazo 
654
        // de estas que tenga el nombre de tabla.
655
        for (ExpressionBuilder.Variable variable : sqlbuilder.variables()) {
656
            if( variable instanceof SQLBuilderBase.ColumnBase ) {
657
                continue;
658
            }
659
            for (String foreingName : foreing_value_args) {
660
                String[] foreingNameParts = foreingName.split("[.]");
661
                if( foreingNameParts.length != 2) {
662
                    continue;
663
                }
664
                String columnNameLocal = foreingNameParts[0];
665
                String columnNameForeing = foreingNameParts[1];
666
                if( !StringUtils.equalsIgnoreCase(variable.name(), columnNameForeing) ) {
667
                    continue;
668
                }
669
                ExpressionBuilder.Variable variable_replacement = sqlbuilder.column(
670
                    table, 
671
                    variable.name()
672
                );
673
                value_replacements.add(
674
                    new ExpressionBuilder.Value[] {
675
                        variable,
676
                        variable_replacement
677
                    }
678
                );
679
            }
680
        }
681
        
682
        // Realizamos los reemplazos calculados previamente (value_replacements).
683
        for (ExpressionBuilder.Value[] replaceValue : value_replacements) {
684
            ExpressionBuilder.Value target = replaceValue[0];
685
            ExpressionBuilder.Value replacement = replaceValue[1];
686
            sqlbuilder.select().replace(target, replacement);    
687
        }
688

  
689
        // A?adimos a la SQL los "LEFT JOIN" que toca para poder acceder
690
        // a los valores referenciados por la funcion FOREING_VALUE.
691
        // Ademas a?adimos los valores referenciados por la funcion FOREING_VALUE
692
        // como columnas de la SQL para poder acceder a ellos si fuese necesario.
693
        for (String foreingName : foreing_value_args) {
694
            String[] foreingNameParts = foreingName.split("[.]");
695
            if( foreingNameParts.length != 2) {
696
                continue;
697
            }
698
            String columnNameLocal = foreingNameParts[0];
699
            String columnNameForeing = foreingNameParts[1];
700
            FeatureAttributeDescriptor attr = type.getAttributeDescriptor(columnNameLocal);
701
            if( attr.isForeingKey() ) {
702
                ForeingKey foreingKey = attr.getForeingKey();
703
                SQLBuilder.TableNameBuilder foreingTable = sqlbuilder.createTableNameBuilder()
704
                        .database(table.getDatabase())
705
                        .schema(table.getSchema()) 
706
                        .name(foreingKey.getTableName());
707
                SQLBuilder.TableNameBuilder mainTable = sqlbuilder.createTableNameBuilder()
708
                        .database(table.getDatabase())
709
                        .schema(table.getSchema()) 
710
                        .name(table.getName());
711

  
712
                sqlbuilder.select().from()
713
                    .left_join(
714
                        foreingTable,
715
                        expbuilder.eq(
716
                                sqlbuilder.column(mainTable, columnNameLocal),
717
                                sqlbuilder.column(foreingTable,foreingKey.getCodeName()) 
718
                        )
719
                    );
720
                sqlbuilder.select().column().name(foreingTable,columnNameForeing);
721
            }
722
        }
723

  
724
        return foreing_value_args.toArray(new String[foreing_value_args.size()]);
725
    }
545 726
}
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/spi/operations/OperationsFactoryBase.java
155 155

  
156 156
    @Override
157 157
    public CalculateEnvelopeOfColumnOperation createCalculateEnvelopeOfColumn(
158
            FeatureType featureType,
158 159
            TableReference table, 
159 160
            String columnName, 
160 161
            String baseFilter, 
......
162 163
            IProjection crs
163 164
        ) {
164 165
        return new CalculateEnvelopeOfColumnOperation(helper, 
165
                table, columnName, baseFilter, workingArea, crs);
166
                featureType, table, columnName, baseFilter, workingArea, crs);
166 167
    }
167 168

  
168 169
    @Override
......
188 189

  
189 190
    @Override
190 191
    public CountOperation createCount(
192
            FeatureType featureType,
191 193
            TableReference table, 
192 194
            String baseFilter, 
193 195
            String filter
194 196
        ) {
195
        return new CountOperation(helper, table, baseFilter, filter);
197
        return new CountOperation(helper, featureType, table, baseFilter, filter);
196 198
    }
197 199

  
198 200
    @Override
199 201
    public TableIsEmptyOperation createTableIsEmpty(
202
            FeatureType featureType,
200 203
            TableReference table,
201 204
            String baseFilter, 
202 205
            String filter
203 206
        ) {
204
        return new TableIsEmptyOperation(helper, table, baseFilter, filter);
207
        return new TableIsEmptyOperation(helper, featureType, table, baseFilter, filter);
205 208
    }
206 209

  
207 210
    @Override
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/spi/operations/ResultSetForSetProviderOperation.java
6 6
import org.apache.commons.lang3.ArrayUtils;
7 7
import org.apache.commons.lang3.StringUtils;
8 8
import org.gvsig.expressionevaluator.ExpressionBuilder;
9
import org.gvsig.expressionevaluator.ExpressionBuilder.Variable;
10 9
import org.gvsig.fmap.dal.exception.DataException;
11 10
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
12 11
import org.gvsig.fmap.dal.feature.FeatureQuery;
......
195 194
        }
196 195
        if( offset>0 ) {
197 196
            sqlbuilder.select().offset(offset);
198
        }
197
        }        
199 198
        sqlbuilder.setProperties(
200 199
                null, 
201 200
                PROP_FEATURE_TYPE, this.storeType,
202 201
                PROP_TABLE, table
203 202
        );
203
        
204
        String[] extraColumnNames = this.helper.replaceForeingValueFunction(sqlbuilder, storeType);
205

  
204 206
        String sql = sqlbuilder.toString();
205 207
        ResultSetEntry resultSetEntry = this.helper.getResulSetControler().create(
206
                sql, fetchSize, columns.toArray(new FeatureAttributeDescriptor[columns.size()])
208
                sql, fetchSize, 
209
                columns.toArray(new FeatureAttributeDescriptor[columns.size()]),
210
                extraColumnNames
207 211
        );
208 212
        return resultSetEntry;
209 213
    }
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/spi/operations/CountOperation.java
7 7
import org.apache.commons.lang3.StringUtils;
8 8
import org.gvsig.expressionevaluator.ExpressionBuilder;
9 9
import org.gvsig.fmap.dal.exception.DataException;
10
import org.gvsig.fmap.dal.feature.FeatureType;
10 11
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
11 12
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
12 13
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
......
20 21
    private final TableReference table;
21 22
    private final String baseFilter;
22 23
    private final String filter;
24
    private final FeatureType featureType;
23 25

  
24 26
    public CountOperation(
25 27
            JDBCHelper helper
26 28
        ) {
27
        this(helper, null, null, null);
29
        this(helper, null, null, null, null);
28 30
    }
29 31

  
30 32
    public CountOperation(
31 33
            JDBCHelper helper,
34
            FeatureType featureType,
32 35
            TableReference table,
33 36
            String baseFilter,
34 37
            String filter
35 38
        ) {
36 39
        super(helper);
40
        this.featureType = featureType;
37 41
        this.table = table;
38 42
        this.baseFilter = baseFilter;
39 43
        this.filter = filter;
......
41 45

  
42 46
    @Override
43 47
    public final Object perform(Connection conn) throws DataException {
44
        return this.count(conn, table, baseFilter, filter);
48
        return this.count(conn, featureType, table, baseFilter, filter);
45 49
    }
46 50

  
47 51
    public long count(Connection conn,
52
            FeatureType featureType,
48 53
            TableReference table,
49 54
            String baseFilter,
50 55
            String filter) throws DataException {
......
65 70
            // El and() hace un set() si no hay un filtro previo
66 71
            sqlbuilder.select().where().and(expbuilder.toValue(filter));
67 72
        }
73
        this.helper.replaceForeingValueFunction(sqlbuilder, featureType);
74
        
68 75
        sqlbuilder.setProperties(
69 76
                ExpressionBuilder.Variable.class, 
70 77
                PROP_TABLE, table
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/spi/operations/FetchFeatureProviderByReferenceOperation.java
119 119
                return null;
120 120
            }
121 121
            FeatureProvider data = this.helper.createFeature(featureType);
122
            this.helper.fetchFeature(data, rs, columns.toArray(new FeatureAttributeDescriptor[columns.size()])); 
122
            this.helper.fetchFeature(data, rs, columns.toArray(new FeatureAttributeDescriptor[columns.size()]), null); 
123 123
            return data;
124 124

  
125 125
        } catch (SQLException ex) {
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/spi/operations/CalculateEnvelopeOfColumnOperation.java
9 9
import org.gvsig.expressionevaluator.ExpressionBuilder;
10 10
import org.gvsig.expressionevaluator.ExpressionBuilder.Variable;
11 11
import org.gvsig.fmap.dal.exception.DataException;
12
import org.gvsig.fmap.dal.feature.FeatureType;
12 13
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
13 14
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
14 15
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
......
25 26
    private final String baseFilter;
26 27
    private final Envelope limit;
27 28
    private final IProjection crs;
29
    private final FeatureType featureType;
28 30

  
29 31
    public CalculateEnvelopeOfColumnOperation(
30 32
            JDBCHelper helper,
33
            FeatureType featureType,
31 34
            TableReference table,
32 35
            String columnName,
33 36
            String baseFilter,
......
35 38
            IProjection crs
36 39
    ) {
37 40
        super(helper);
41
        this.featureType = featureType;
38 42
        this.table = table;
39 43
        this.columnName = columnName;
40 44
        this.baseFilter = baseFilter;
......
46 50
    public final Object perform(Connection conn) throws DataException {
47 51
        Envelope env = calculateEnvelopeOfColumn(
48 52
            conn,
53
            featureType,
49 54
            table,
50 55
            columnName,
51 56
            baseFilter,
......
57 62

  
58 63
    public Envelope calculateEnvelopeOfColumn(
59 64
            Connection conn,
65
            FeatureType featureType,
60 66
            TableReference table,
61 67
            String columnName,
62 68
            String baseFilter,
......
124 130
        sqlbuilder.select().where().and(        
125 131
            expbuilder.not_is_null(expbuilder.column(columnName))
126 132
        );
127
        
133
        this.helper.replaceForeingValueFunction(sqlbuilder, featureType);
128 134
        sqlbuilder.setProperties(
129 135
                Variable.class, 
130 136
                PROP_TABLE, table
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/spi/operations/TableIsEmptyOperation.java
7 7
import org.apache.commons.lang3.StringUtils;
8 8
import org.gvsig.expressionevaluator.ExpressionBuilder;
9 9
import org.gvsig.fmap.dal.exception.DataException;
10
import org.gvsig.fmap.dal.feature.FeatureType;
10 11
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
11 12
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
12 13
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
......
20 21
    private final TableReference table;
21 22
    private final String baseFilter;
22 23
    private final String filter;
24
    private final FeatureType featureType;
23 25

  
24 26
    public TableIsEmptyOperation(
25 27
            JDBCHelper helper
26 28
        ) {
27
        this(helper, null, null, null);
29
        this(helper, null, null, null, null);
28 30
    }
29 31

  
30 32
    public TableIsEmptyOperation(
31 33
            JDBCHelper helper,
34
            FeatureType featureType,
32 35
            TableReference table,
33 36
            String baseFilter,
34 37
            String filter
35 38
        ) {
36 39
        super(helper);
40
        this.featureType = featureType;
37 41
        this.table = table;
38 42
        this.baseFilter = baseFilter;
39 43
        this.filter = filter;
......
41 45

  
42 46
    @Override
43 47
    public final Object perform(Connection conn) throws DataException {
44
        return this.tableIsEmpty(conn, table, baseFilter, filter);
48
        return this.tableIsEmpty(conn, featureType, table, baseFilter, filter);
45 49
    }
46 50

  
47 51
    public boolean tableIsEmpty(Connection conn,
52
            FeatureType featureType,
48 53
            TableReference table,
49 54
            String baseFilter,
50 55
            String filter
......
67 72
            sqlbuilder.select().where().and(expbuilder.toValue(filter));
68 73
        }
69 74
        sqlbuilder.select().limit(1);
75
        this.helper.replaceForeingValueFunction(sqlbuilder, featureType);
70 76
        sqlbuilder.setProperties(
71 77
                ExpressionBuilder.Variable.class, 
72 78
                PROP_TABLE, table
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/spi/operations/FetchFeatureTypeOperation.java
28 28
@SuppressWarnings("UseSpecificCatch")
29 29
public class FetchFeatureTypeOperation extends AbstractConnectionOperation {
30 30
    private final EditableFeatureType featureType;
31
    private final TableReference table;
31
    protected final TableReference table;
32 32
    private final List<String> primaryKeys;
33 33
    private final String defaultGeometryColumn;
34 34
    private final IProjection crs;
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/spi/JDBCStoreProviderBase.java
73 73

  
74 74
        @Override
75 75
        public void calculate() {
76
            JDBCStoreParameters params = getParameters();
77
            CountOperation count = getOperations().createCount(
78
                    getOperations().createTableReference(params),
79
                    params.getBaseFilter(), 
80
                    null
81
            );
82
            this.value = (Long) count.perform();            
76
            try {
77
                JDBCStoreParameters params = getParameters();
78
                CountOperation count = getOperations().createCount(
79
                        getFeatureStore().getDefaultFeatureType(),
80
                        getOperations().createTableReference(params),
81
                        params.getBaseFilter(),
82
                        null
83
                );            
84
                this.value = (Long) count.perform();
85
            } catch (DataException ex) {
86
                throw new RuntimeException("Can't calculate count",ex);
87
            }
83 88
        }
84 89
        
85 90
        @Override
......
117 122
                JDBCStoreParameters params = getParameters();
118 123
                CalculateEnvelopeOfColumnOperation calculateEnvelopeOfColumn = 
119 124
                    getOperations().createCalculateEnvelopeOfColumn(
125
                        getFeatureStore().getDefaultFeatureType(),
120 126
                        getOperations().createTableReference(params),
121 127
                        columnName, 
122 128
                        params.getBaseFilter(), 
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/ResulSetControler.java
16 16
        public boolean isZombie();
17 17
        public String getSQL();
18 18
        public FeatureAttributeDescriptor[] getColumns();
19
        public String[] getExtraValueNames();
19 20
        public Object getObject(int columnIndex) throws SQLException;
20 21
        public byte[] getBytes(int columnIndex) throws SQLException;
21 22
        public boolean next() throws SQLException;
......
25 26

  
26 27
    public long getTimeToZombie();
27 28

  
28
    public ResultSetEntry create(String sql, int fetchSize, FeatureAttributeDescriptor[] columns ) throws DataException;
29
    public ResultSetEntry create(String sql, int fetchSize, FeatureAttributeDescriptor[] columns, String[] extraValueNames ) throws DataException;
29 30

  
30
    public ResultSetEntry create(String sql, List<Object> values, int fetchSize, FeatureAttributeDescriptor[] columns ) throws DataException;
31
    public ResultSetEntry create(String sql, List<Object> values, int fetchSize, FeatureAttributeDescriptor[] columns, String[] extraValueNames) throws DataException;
31 32

  
32 33
    public int getOpenCount();
33 34
    
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/impl/JDBCSetProvider.java
175 175
                filtersql = filter.getSQL();
176 176
            }
177 177
            CountOperation selectCount = this.getOperations().createCount(
178
                    this.getFeatureType(),
178 179
                    this.getOperations().createTableReference(params),
179 180
                    params.getBaseFilter(), 
180 181
                    filtersql
......
195 196
                    filtersql = filter.getSQL();
196 197
                }
197 198
                TableIsEmptyOperation isEmpty_ = this.getOperations().createTableIsEmpty(
199
                        this.getFeatureType(),
198 200
                        this.getOperations().createTableReference(params),
199 201
                        params.getBaseFilter(), 
200 202
                        filtersql
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/impl/ResulSetControlerBase.java
32 32
        private long lastUse = 0;
33 33
        private String sql;
34 34
        private final FeatureAttributeDescriptor[] columns;
35
        private final String[] extraValueNames;
35 36

  
36
        public ResultSetEntryBase(ResultSet resulSet, FeatureAttributeDescriptor[] columns) {
37
            this(resulSet,null, columns);
38
        }
39

  
40
        public ResultSetEntryBase(ResultSet resulSet, String sql, FeatureAttributeDescriptor[] columns) {
37
        public ResultSetEntryBase(ResultSet resulSet, String sql, FeatureAttributeDescriptor[] columns, String[] extraValueNames) {
41 38
            this.resultSet = resulSet;
42 39
            this.id = nextid++;
43 40
            this.sql = sql;
44 41
            this.columns = columns;
42
            this.extraValueNames = extraValueNames;
45 43
            used();
46 44
            resulSets.put(this.getID(), this);
47 45
        }
......
75 73
        }
76 74

  
77 75
        @Override
76
        public String[] getExtraValueNames() {
77
            return this.extraValueNames;
78
        }
79
        
80
        @Override
78 81
        public FeatureAttributeDescriptor[] getColumns() {
79 82
            return this.columns;
80 83
        }
......
163 166
    public ResultSetEntryBase create(
164 167
            String sql, 
165 168
            int fetchSize, 
166
            FeatureAttributeDescriptor[] columns) throws DataException {
167
        return create(sql, null, fetchSize, columns);
169
            FeatureAttributeDescriptor[] columns,
170
            String[] extraValueNames) throws DataException {
171
        return create(sql, null, fetchSize, columns, extraValueNames);
168 172
    }
169 173

  
170 174
    @Override
171 175
    public synchronized ResultSetEntryBase create(
172
            final String sql,
173
            final List values,
174
            final int fetchSize, 
175
            FeatureAttributeDescriptor[] columns) throws DataException {
176

  
176
            String sql, 
177
            List<Object> values, 
178
            int fetchSize, 
179
            FeatureAttributeDescriptor[] columns, 
180
            String[] extraValueNames) throws DataException {
177 181
        this.pack();
178 182
        ResultSet rs = null;
179 183
        Connection conn = null;
......
196 200
            if (fetchSize > 0) {
197 201
                rs.setFetchSize(fetchSize);
198 202
            }
199
            ResultSetEntryBase rsentry = new ResultSetEntryBase(rs, sql, columns);
203
            ResultSetEntryBase rsentry = new ResultSetEntryBase(rs, sql, columns,  extraValueNames);
200 204
            return rsentry;
201 205

  
202 206
        } catch (SQLException e) {
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/JDBCHelper.java
3 3
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
4 4
import java.sql.Connection;
5 5
import java.sql.ResultSet;
6
import java.util.List;
6 7
import org.gvsig.expressionevaluator.ExpressionBuilder.GeometrySupportType;
8
import org.gvsig.fmap.dal.SQLBuilder;
7 9
import org.gvsig.fmap.dal.exception.DataException;
8 10
import org.gvsig.fmap.dal.exception.InitializeException;
9 11
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
10 12
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
11
import org.gvsig.fmap.dal.feature.FeatureStore;
12 13
import org.gvsig.fmap.dal.feature.FeatureType;
13 14
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
14 15
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
......
136 137
    public void fetchFeature(
137 138
            FeatureProvider feature, 
138 139
            ResultSet rs,
139
            FeatureAttributeDescriptor[] columns
140
            FeatureAttributeDescriptor[] columns,
141
            String[] extraValueNames
140 142
    ) throws DataException;
141 143
    
142 144
    public void fetchFeature(
......
181 183
    public String getSourceId(JDBCStoreParameters parameters);
182 184

  
183 185
    public boolean isThreadSafe();
186
    
187
    public String[] replaceForeingValueFunction(SQLBuilder sqlbuilder, FeatureType type);
184 188
}
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.h2/src/main/java/org/gvsig/fmap/dal/store/h2/operations/H2SpatialFetchFeatureTypeOperation.java
15 15
import org.gvsig.fmap.dal.exception.DataException;
16 16
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
17 17
import org.gvsig.fmap.dal.feature.EditableFeatureType;
18
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
18 19
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
19 20
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
20 21
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory.TableReference;
......
79 80
        super(helper, featureType, table, primaryKeys, defaultGeometryColumn, crs);
80 81
    }            
81 82

  
82
    @Override
83
    public void fetch(EditableFeatureType featureType, Connection conn, TableReference table, List<String> pks, String defaultGeometryColumn, IProjection crs) throws DataException {
84
        geometry_column = new HashMap<>();
85
        try {
86
            //
87
            // https://github.com/orbisgis/h2gis/wiki/1.-Spatial-data#geometry-columns-view
88
            //
89
            StringBuilder where = null;
90
            if( table.hasDatabase() ) {
91
                if( where == null ) {
92
                    where = new StringBuilder();
93
                } else {
94
                    where.append(" AND ");
83
    private GeometryColumnInfo getGeometryColumnInfo(String name) {
84
        if( geometry_column==null ) {
85
            geometry_column = new HashMap<>();
86
            try {
87
                //
88
                // https://github.com/orbisgis/h2gis/wiki/1.-Spatial-data#geometry-columns-view
89
                //
90
                StringBuilder where = null;
91
                if( table.hasDatabase() ) {
92
                    if( where == null ) {
93
                        where = new StringBuilder();
94
                    } else {
95
                        where.append(" AND ");
96
                    }
97
                    where.append("UPPER(F_TABLE_CATALOG) = '");
98
                    where.append(table.getDatabase().toUpperCase());
99
                    where.append("'");
95 100
                }
96
                where.append("UPPER(F_TABLE_CATALOG) = '");
97
                where.append(table.getDatabase().toUpperCase());
98
                where.append("'");
99
            }
100
            if( table.hasSchema()) {
101
                if( where == null ) {
102
                    where = new StringBuilder();
103
                } else {
104
                    where.append(" AND ");
101
                if( table.hasSchema()) {
102
                    if( where == null ) {
103
                        where = new StringBuilder();
104
                    } else {
105
                        where.append(" AND ");
106
                    }
107
                    where.append("UPPER(F_TABLE_SCHEMA) = '");
108
                    where.append(table.getSchema().toUpperCase());
109
                    where.append("'");
105 110
                }
106
                where.append("UPPER(F_TABLE_SCHEMA) = '");
107
                where.append(table.getSchema().toUpperCase());
108
                where.append("'");
109
            }
110
            if( table.hasTable()) {
111
                if( where == null ) {
112
                    where = new StringBuilder();
113
                } else {
114
                    where.append(" AND ");
111
                if( table.hasTable()) {
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff