Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.h2spatial / org.gvsig.h2spatial.h2gis132 / org.gvsig.h2spatial.h2gis132.provider / src / main / java / org / gvsig / fmap / dal / store / h2 / operations / H2SpatialFetchFeatureTypeOperation.java @ 46315

History | View | Annotate | Download (11.4 KB)

1

    
2
package org.gvsig.fmap.dal.store.h2.operations;
3

    
4
import java.sql.ResultSet;
5
import java.sql.ResultSetMetaData;
6
import java.sql.SQLException;
7
import java.sql.Statement;
8
import java.util.HashMap;
9
import java.util.List;
10
import java.util.Map;
11
import org.cresques.cts.IProjection;
12
import org.gvsig.expressionevaluator.ExpressionBuilder;
13
import org.gvsig.fmap.dal.DataTypes;
14
import org.gvsig.fmap.dal.exception.DataException;
15
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
16
import org.gvsig.fmap.dal.feature.EditableFeatureType;
17
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
18
import org.gvsig.fmap.dal.store.jdbc2.JDBCConnection;
19
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
20
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
21
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory.TableReference;
22
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
23
import org.gvsig.fmap.dal.store.jdbc2.spi.SRSSolver;
24
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.FetchFeatureTypeOperation;
25
import org.gvsig.fmap.geom.Geometry;
26
import org.gvsig.fmap.geom.GeometryLocator;
27
import org.gvsig.fmap.geom.GeometryManager;
28
import org.gvsig.fmap.geom.type.GeometryType;
29

    
30
@SuppressWarnings("UseSpecificCatch")
31
public class H2SpatialFetchFeatureTypeOperation extends FetchFeatureTypeOperation {
32

    
33
    private static Map<String,GeometryType>h2spatialGeometryTypes = null;
34
    private Map<String,GeometryColumnInfo> geometry_column;
35
    
36
    private static class GeometryColumnInfo {
37
        
38
        public String columnName;
39
        public int geometryType;
40
        public String geometryTypeName;
41
        public int dimensions;
42
        public int srid;
43
        
44
        public GeometryColumnInfo(String columnName, int geometryType, String geometryTypeName, int dimensions, int srid) {
45
            this.columnName = columnName;
46
            this.geometryType = geometryType;
47
            this.geometryTypeName = geometryTypeName;
48
            this.dimensions = dimensions;
49
            this.srid = srid;
50
        }
51
    }
52
    
53
    
54
    public H2SpatialFetchFeatureTypeOperation(
55
            JDBCHelper helper
56
        ) {
57
        super(helper);
58
    }
59

    
60
    private GeometryType getGT(
61
            GeometryManager manager, 
62
            int type, 
63
            int subtype
64
        ) {
65
        try {
66
            return manager.getGeometryType(type, subtype);
67
        } catch (Exception ex) {
68
            return null;
69
        }
70
    }
71
    
72
    public H2SpatialFetchFeatureTypeOperation(
73
            JDBCHelper helper,
74
            EditableFeatureType featureType,
75
            TableReference table,
76
            List<String> primaryKeys,
77
            String defaultGeometryColumn,
78
            IProjection crs,
79
            int geometryType,
80
            int geometrySubtype
81
        ) {
82
        super(helper, featureType, table, primaryKeys, defaultGeometryColumn, crs, geometryType, geometrySubtype);
83
    }            
84

    
85
    private GeometryColumnInfo getGeometryColumnInfo(String name) {
86
        if( geometry_column==null ) {
87
            geometry_column = new HashMap<>();
88
            try {
89
                //
90
                // https://github.com/orbisgis/h2gis/wiki/1.-Spatial-data#geometry-columns-view
91
                //
92
                StringBuilder where = null;
93
                if( table.hasDatabase() ) {
94
                    if( where == null ) {
95
                        where = new StringBuilder();
96
                    } else {
97
                        where.append(" AND ");
98
                    }
99
                    where.append("UPPER(F_TABLE_CATALOG) = '");
100
                    where.append(table.getDatabase().toUpperCase());
101
                    where.append("'");
102
                }
103
                if( table.hasSchema()) {
104
                    if( where == null ) {
105
                        where = new StringBuilder();
106
                    } else {
107
                        where.append(" AND ");
108
                    }
109
                    where.append("UPPER(F_TABLE_SCHEMA) = '");
110
                    where.append(table.getSchema().toUpperCase());
111
                    where.append("'");
112
                }
113
                if( table.hasTable()) {
114
                    if( where == null ) {
115
                        where = new StringBuilder();
116
                    } else {
117
                        where.append(" AND ");
118
                    }
119
                    where.append("UPPER(F_TABLE_NAME) = '");
120
                    where.append(table.getTable().toUpperCase());
121
                    where.append("'");
122
                }            
123
                String sql = "SELECT F_GEOMETRY_COLUMN, GEOMETRY_TYPE, COORD_DIMENSION, SRID, TYPE FROM GEOMETRY_COLUMNS WHERE " + where;
124
                Statement st = this.getConnection().createStatement();
125
                ResultSet rs = JDBCUtils.executeQuery(st,sql);
126
                while( rs.next() ) {
127
                    geometry_column.put(
128
                        rs.getString("F_GEOMETRY_COLUMN"), 
129
                        new GeometryColumnInfo(
130
                            rs.getString("F_GEOMETRY_COLUMN"), 
131
                            rs.getInt("GEOMETRY_TYPE"), 
132
                            rs.getString("TYPE"), 
133
                            rs.getInt("COORD_DIMENSION"), 
134
                            rs.getInt("SRID")
135
                        )
136
                    );
137
                }
138
            } catch (SQLException | AccessResourceException ex) {
139
                LOGGER.warn("Can't read metadata from table '"+table+"'.",ex);
140
            }
141
        }
142
        return this.geometry_column.get(name);
143
    }
144
    
145
    @Override
146
    public void fetch(JDBCConnection conn) throws DataException {
147
        super.fetch(conn);
148
    }
149
        
150
    @Override
151
    protected void fetchGeometryTypeAndSRS(
152
            EditableFeatureAttributeDescriptor attr,
153
            ResultSetMetaData rsMetadata,
154
            int colIndex
155
        ) {
156
        try {
157
            if( attr.getType()==DataTypes.GEOMETRY ) {
158
                GeometryColumnInfo column_info = this.getGeometryColumnInfo(attr.getName());
159
                String type = "GEOMETRY";
160
                if( column_info!=null ) {
161
                    // H2GIS solo soporte 2D y 3D no soporta Ms
162
                    if( column_info.dimensions==3 ) {
163
                        type = column_info.geometryTypeName+"Z";
164
                    } else {
165
                        type = column_info.geometryTypeName;
166
                    }
167
                    SRSSolver solver = this.helper.getSRSSolver();
168
                    attr.setSRS(
169
                        solver.getProjection(getConnection(), column_info.srid)
170
                    );
171
                }
172
                GeometryType gt = getGeometryTypeFromH2SpatialType(type);
173
                if( gt != null ) {
174
                    attr.setGeometryType(gt);
175
                }
176
            }
177
        } catch(Exception ex) {
178
            throw new RuntimeException("Can't fetch geometry type and SRS.", ex);
179
        }
180
    }
181

    
182
    private GeometryType getGeometryTypeFromH2SpatialType(String typeName) {
183
        if( h2spatialGeometryTypes==null ) {
184
            //
185
            // https://github.com/orbisgis/h2gis/wiki/1.-Spatial-data#geometry-columns-view
186
            //
187
            GeometryManager manager = GeometryLocator.getGeometryManager();
188
            h2spatialGeometryTypes = new HashMap<>();
189
            h2spatialGeometryTypes.put("POINT", getGT(manager, Geometry.TYPES.POINT,Geometry.SUBTYPES.GEOM2D));
190
            h2spatialGeometryTypes.put("POINTZ", getGT(manager, Geometry.TYPES.POINT,Geometry.SUBTYPES.GEOM3D));
191
            
192
            h2spatialGeometryTypes.put("LINESTRING", getGT(manager, Geometry.TYPES.LINE,Geometry.SUBTYPES.GEOM2D));
193
            h2spatialGeometryTypes.put("LINESTRINGZ", getGT(manager, Geometry.TYPES.LINE,Geometry.SUBTYPES.GEOM3D));
194
            
195
            h2spatialGeometryTypes.put("POLYGON", getGT(manager, Geometry.TYPES.POLYGON,Geometry.SUBTYPES.GEOM2D));
196
            h2spatialGeometryTypes.put("POLYGONZ", getGT(manager, Geometry.TYPES.POLYGON,Geometry.SUBTYPES.GEOM3D));
197

    
198
            h2spatialGeometryTypes.put("MULTIPOINT", getGT(manager, Geometry.TYPES.MULTIPOINT,Geometry.SUBTYPES.GEOM2D));
199
            h2spatialGeometryTypes.put("MULTIPOINTZ", getGT(manager, Geometry.TYPES.MULTIPOINT,Geometry.SUBTYPES.GEOM3D));
200

    
201
            h2spatialGeometryTypes.put("MULTILINESTRING", getGT(manager, Geometry.TYPES.MULTILINE,Geometry.SUBTYPES.GEOM2D));
202
            h2spatialGeometryTypes.put("MULTILINESTRINGZ", getGT(manager, Geometry.TYPES.MULTILINE,Geometry.SUBTYPES.GEOM3D));
203

    
204
            h2spatialGeometryTypes.put("MULTIPOLYGON", getGT(manager, Geometry.TYPES.MULTIPOLYGON,Geometry.SUBTYPES.GEOM2D));
205
            h2spatialGeometryTypes.put("MULTIPOLYGONZ", getGT(manager, Geometry.TYPES.MULTIPOLYGON,Geometry.SUBTYPES.GEOM3D));
206

    
207
            h2spatialGeometryTypes.put("GEOMETRY", getGT(manager, Geometry.TYPES.GEOMETRY,Geometry.SUBTYPES.GEOM2D));
208
            h2spatialGeometryTypes.put("GEOMETRYZ", getGT(manager, Geometry.TYPES.GEOMETRY,Geometry.SUBTYPES.GEOM3D));
209

    
210
            h2spatialGeometryTypes.put("GEOMCOLLECTION", getGT(manager, Geometry.TYPES.GEOMETRY,Geometry.SUBTYPES.GEOM2D));
211
            h2spatialGeometryTypes.put("GEOMCOLLECTIONZ", getGT(manager, Geometry.TYPES.GEOMETRY,Geometry.SUBTYPES.GEOM3D));
212
        }
213
        return h2spatialGeometryTypes.get(typeName);
214
    }
215

    
216
    @Override
217
    public String getSQLToRetrievePrimaryKeysFromInformationSchema() throws SQLException {
218
        JDBCSQLBuilderBase sqlbuilder = this.createSQLBuilder();
219
        ExpressionBuilder expbuilder = sqlbuilder.expression();
220

    
221
        sqlbuilder.select().column().name("COLUMN_LIST");
222
        sqlbuilder.select().column().name("CONSTRAINT_TYPE");
223
        sqlbuilder.select().from().table().schema("INFORMATION_SCHEMA").name("CONSTRAINTS");
224
        sqlbuilder.select().where().set(
225
                expbuilder.like(
226
                        expbuilder.column("TABLE_NAME"), 
227
                        expbuilder.constant(table.getTable())
228
                )
229
        );
230
        if( table.hasSchema() ) {
231
            sqlbuilder.select().where().and(
232
                    expbuilder.like(
233
                            expbuilder.column("TABLE_SCHEMA"),
234
                            expbuilder.constant(table.getSchema())
235
                    )
236
            );
237
        }
238
//        if (catalog != null) {
239
//            sqlbuilder.select().where().and(
240
//                    expbuilder.like(
241
//                            expbuilder.column("CONSTRAINT_CATALOG"),
242
//                            expbuilder.constant(catalog)
243
//                    )
244
//            );
245
//        }
246
        sqlbuilder.select().where().and(
247
                expbuilder.eq(
248
                        expbuilder.column("CONSTRAINT_TYPE"),
249
                        expbuilder.constant("PRIMARY KEY")
250
                )
251
        );
252
        return sqlbuilder.toString();
253
    }
254
    
255
//    @Override
256
//    public String getSQLToRetrieveFirstRowOfTable() {
257
//        String subQuery = this.table.getSubquery();
258
//        if(StringUtils.isBlank(subQuery)){
259
//            return super.getSQLToRetrieveFirstRowOfTable();
260
//        }
261
//        if(StringUtils.containsIgnoreCase(subQuery, " limit ")){
262
//            return super.getSQLToRetrieveFirstRowOfTable();
263
//        }
264
//        return subQuery+" limit 1";
265
//    }
266

    
267
}