Statistics
| Revision:

root / trunk / org.gvsig.postgresql / org.gvsig.postgresql.provider / src / main / java / org / gvsig / postgresql / dal / operations / PostgreSQLFetchFeatureTypeOperation.java @ 511

History | View | Annotate | Download (11.3 KB)

1

    
2
package org.gvsig.postgresql.dal.operations;
3

    
4
import java.sql.Connection;
5
import java.sql.ResultSet;
6
import java.sql.ResultSetMetaData;
7
import java.sql.SQLException;
8
import java.sql.Statement;
9
import java.util.HashMap;
10
import java.util.List;
11
import java.util.Map;
12
import org.apache.commons.lang3.StringUtils;
13
import org.cresques.cts.IProjection;
14
import org.gvsig.expressionevaluator.ExpressionBuilder;
15
import org.gvsig.fmap.dal.DataTypes;
16
import org.gvsig.fmap.dal.exception.DataException;
17
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
18
import org.gvsig.fmap.dal.feature.EditableFeatureType;
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
import org.gvsig.postgresql.dal.PostgreSQLBuilder;
30

    
31
@SuppressWarnings("UseSpecificCatch")
32
public class PostgreSQLFetchFeatureTypeOperation extends FetchFeatureTypeOperation {
33

    
34
    private static Map<String,GeometryType>databaseGeometryTypes = null;
35
    
36
    public PostgreSQLFetchFeatureTypeOperation(
37
            JDBCHelper helper
38
        ) {
39
        super(helper);
40
    }
41

    
42
    private GeometryType getGT(
43
            GeometryManager manager, 
44
            int type, 
45
            int subtype
46
        ) {
47
        try {
48
            return manager.getGeometryType(type, subtype);
49
        } catch (Exception ex) {
50
            return null;
51
        }
52
    }
53
    
54
    public PostgreSQLFetchFeatureTypeOperation(
55
            JDBCHelper helper,
56
            EditableFeatureType featureType,
57
            TableReference table,
58
            List<String> primaryKeys,
59
            String defaultGeometryColumn,
60
            IProjection crs
61
        ) {
62
        super(helper, featureType, table, primaryKeys, defaultGeometryColumn, crs);
63
    }            
64

    
65
    @Override
66
    public void fetch(EditableFeatureType featureType, Connection conn, TableReference table, List<String> pks, String defaultGeometryColumn, IProjection crs) throws DataException {
67
        super.fetch(featureType, conn, table, pks, defaultGeometryColumn, crs);
68
    }
69

    
70
    @Override
71
    protected int getDataTypeFromMetadata(
72
            ResultSetMetaData rsMetadata,
73
            int colIndex
74
        ) throws SQLException {
75

    
76
        return super.getDataTypeFromMetadata(rsMetadata, colIndex);
77
    }
78
    
79
    @Override
80
    protected String getSQLToRetrievePrimaryKeysFromInformationSchema(
81
            String catalog,
82
            String schema,
83
            String table
84
        ) throws SQLException {
85
        PostgreSQLBuilder sqlbuilder = (PostgreSQLBuilder) this.createSQLBuilder();
86
        ExpressionBuilder expbuilder = sqlbuilder.expression();
87
        
88
        String column_COLUMN_NAME = "column_name";
89
        String column_CONSTRAINT_TYPE = "constraint_type";
90
        
91
        if( sqlbuilder.getDatabaseVersion().getMajor()<10 ) {
92
            column_COLUMN_NAME = "COLUMN_NAME";
93
            column_CONSTRAINT_TYPE = "CONSTRAINT_TYPE";
94
        }
95
        sqlbuilder.select().column().name(column_COLUMN_NAME);
96
        sqlbuilder.select().column().name(column_CONSTRAINT_TYPE);
97
        sqlbuilder.select().from().custom(
98
                "INFORMATION_SCHEMA.table_constraints t_cons "
99
                + "inner join INFORMATION_SCHEMA.key_column_usage c on "
100
                + "c.constraint_catalog = t_cons.constraint_catalog and "
101
                + "c.table_schema = t_cons.table_schema and "
102
                + "c.table_name = t_cons.table_name and "
103
                + "c.constraint_name = t_cons.constraint_name "
104
        );
105
        sqlbuilder.select().where().set(
106
                expbuilder.like(
107
                        expbuilder.custom("c.TABLE_NAME"), 
108
                        expbuilder.constant(table)
109
                )
110
        );
111
        if (schema != null) {
112
            sqlbuilder.select().where().and(
113
                    expbuilder.like(
114
                            expbuilder.custom("c.TABLE_SCHEMA"),
115
                            expbuilder.constant(schema)
116
                    )
117
            );
118
        }
119
        if (catalog != null) {
120
            sqlbuilder.select().where().and(
121
                    expbuilder.like(
122
                            expbuilder.custom("c.CONSTRAINT_CATALOG"),
123
                            expbuilder.constant(catalog)
124
                    )
125
            );
126
        }
127
        sqlbuilder.select().where().and(
128
                expbuilder.eq(
129
                        expbuilder.column(column_CONSTRAINT_TYPE),
130
                        expbuilder.constant("PRIMARY KEY")
131
                )
132
        );
133
        return sqlbuilder.toString();
134
    }
135
        
136
    @Override
137
    protected void fetchGeometryTypeAndSRS(
138
            EditableFeatureAttributeDescriptor attr,
139
            ResultSetMetaData rsMetadata,
140
            int colIndex
141
        ) {
142
        if( attr.getType()!=DataTypes.GEOMETRY ) {
143
            return;
144
        }
145
        try {
146
            JDBCSQLBuilderBase sqlbuilder = this.createSQLBuilder();
147
            ExpressionBuilder expbuilder = sqlbuilder.expression();
148
            
149
            sqlbuilder.select().column().name("f_table_catalog");
150
            sqlbuilder.select().column().name("f_table_schema");
151
            sqlbuilder.select().column().name("f_table_name");
152
            sqlbuilder.select().column().name("f_geometry_column");
153
            sqlbuilder.select().column().name("coord_dimension");
154
            sqlbuilder.select().column().name("srid");
155
            sqlbuilder.select().column().name("type");
156
            sqlbuilder.select().where().set(
157
                    expbuilder.eq(
158
                            expbuilder.column("f_table_name"),
159
                            expbuilder.constant(this.getTable().getTable())
160
                    )
161
            );                
162
            sqlbuilder.select().where().and(
163
                    expbuilder.eq(
164
                            expbuilder.column("f_geometry_column"),
165
                            expbuilder.constant(attr.getName())
166
                    )
167
            );         
168
            sqlbuilder.select().from().table().name("geometry_columns");
169
            Statement st = null;
170
            ResultSet rs = null;
171
            
172
            Integer srsid = null;
173
            String geometryTypeName = null;
174
            try {
175
                st = this.getConnection().createStatement();
176
                rs = JDBCUtils.executeQuery(st, sqlbuilder.toString());
177
                if (rs.next()) {
178
                    srsid = rs.getInt("srid");
179
                    geometryTypeName = rs.getString("type");
180
                }
181
            } finally {
182
                JDBCUtils.closeQuietly(rs);
183
                JDBCUtils.closeQuietly(st);
184
            }
185
            if( !StringUtils.isEmpty(geometryTypeName) ) {
186
                GeometryType gt = getGeometryTypeFromDatabaseTypeName(geometryTypeName);
187
                attr.setGeometryType(gt);
188
            }
189
            if( srsid!=null ) {
190
                SRSSolver srssolver = this.helper.getSRSSolver();
191
                attr.setSRS(srssolver.getProjection(this.getConnection(),srsid));
192
            }
193
        } catch (Exception ex) {
194
            LOGGER.debug("Can't get geometry type and srs from column '"+attr.getName()+"'.",ex);
195
        }
196
    }
197

    
198
    private GeometryType getGeometryTypeFromDatabaseTypeName(String typeName) {
199
        if( databaseGeometryTypes==null ) {
200
            GeometryManager manager = GeometryLocator.getGeometryManager();
201
            databaseGeometryTypes = new HashMap<>();
202
            databaseGeometryTypes.put("POINT", getGT(manager, Geometry.TYPES.POINT,Geometry.SUBTYPES.GEOM2D));
203
            databaseGeometryTypes.put("POINTZ", getGT(manager, Geometry.TYPES.POINT,Geometry.SUBTYPES.GEOM3D));
204
            databaseGeometryTypes.put("POINTM", getGT(manager, Geometry.TYPES.POINT,Geometry.SUBTYPES.GEOM2DM));
205
            databaseGeometryTypes.put("POINTZM", getGT(manager, Geometry.TYPES.POINT,Geometry.SUBTYPES.GEOM3DM));
206
            
207
            databaseGeometryTypes.put("LINESTRING", getGT(manager, Geometry.TYPES.LINE,Geometry.SUBTYPES.GEOM2D));
208
            databaseGeometryTypes.put("LINESTRINGZ", getGT(manager, Geometry.TYPES.LINE,Geometry.SUBTYPES.GEOM3D));
209
            databaseGeometryTypes.put("LINESTRINGM", getGT(manager, Geometry.TYPES.LINE,Geometry.SUBTYPES.GEOM2DM));
210
            databaseGeometryTypes.put("LINESTRINGZM", getGT(manager, Geometry.TYPES.LINE,Geometry.SUBTYPES.GEOM3DM));
211
            
212
            databaseGeometryTypes.put("POLYGON", getGT(manager, Geometry.TYPES.POLYGON,Geometry.SUBTYPES.GEOM2D));
213
            databaseGeometryTypes.put("POLYGONZ", getGT(manager, Geometry.TYPES.POLYGON,Geometry.SUBTYPES.GEOM3D));
214
            databaseGeometryTypes.put("POLYGONM", getGT(manager, Geometry.TYPES.POLYGON,Geometry.SUBTYPES.GEOM2DM));
215
            databaseGeometryTypes.put("POLYGONZM", getGT(manager, Geometry.TYPES.POLYGON,Geometry.SUBTYPES.GEOM3DM));
216

    
217
            databaseGeometryTypes.put("MULTIPOINT", getGT(manager, Geometry.TYPES.MULTIPOINT,Geometry.SUBTYPES.GEOM2D));
218
            databaseGeometryTypes.put("MULTIPOINTZ", getGT(manager, Geometry.TYPES.MULTIPOINT,Geometry.SUBTYPES.GEOM3D));
219
            databaseGeometryTypes.put("MULTIPOINTM", getGT(manager, Geometry.TYPES.MULTIPOINT,Geometry.SUBTYPES.GEOM2DM));
220
            databaseGeometryTypes.put("MULTIPOINTZM", getGT(manager, Geometry.TYPES.MULTIPOINT,Geometry.SUBTYPES.GEOM3DM));
221

    
222
            databaseGeometryTypes.put("MULTILINESTRING", getGT(manager, Geometry.TYPES.MULTILINE,Geometry.SUBTYPES.GEOM2D));
223
            databaseGeometryTypes.put("MULTILINESTRINGZ", getGT(manager, Geometry.TYPES.MULTILINE,Geometry.SUBTYPES.GEOM3D));
224
            databaseGeometryTypes.put("MULTILINESTRINGM", getGT(manager, Geometry.TYPES.MULTILINE,Geometry.SUBTYPES.GEOM2DM));
225
            databaseGeometryTypes.put("MULTILINESTRINGZM", getGT(manager, Geometry.TYPES.MULTILINE,Geometry.SUBTYPES.GEOM3DM));
226

    
227
            databaseGeometryTypes.put("MULTIPOLYGON", getGT(manager, Geometry.TYPES.MULTIPOLYGON,Geometry.SUBTYPES.GEOM2D));
228
            databaseGeometryTypes.put("MULTIPOLYGONZ", getGT(manager, Geometry.TYPES.MULTIPOLYGON,Geometry.SUBTYPES.GEOM3D));
229
            databaseGeometryTypes.put("MULTIPOLYGONM", getGT(manager, Geometry.TYPES.MULTIPOLYGON,Geometry.SUBTYPES.GEOM2DM));
230
            databaseGeometryTypes.put("MULTIPOLYGONZM", getGT(manager, Geometry.TYPES.MULTIPOLYGON,Geometry.SUBTYPES.GEOM3DM));
231

    
232
            databaseGeometryTypes.put("GEOMETRY", getGT(manager, Geometry.TYPES.GEOMETRY,Geometry.SUBTYPES.GEOM2D));
233
            databaseGeometryTypes.put("GEOMETRYZ", getGT(manager, Geometry.TYPES.GEOMETRY,Geometry.SUBTYPES.GEOM3D));
234
            databaseGeometryTypes.put("GEOMETRYM", getGT(manager, Geometry.TYPES.GEOMETRY,Geometry.SUBTYPES.GEOM2DM));
235
            databaseGeometryTypes.put("GEOMETRYZM", getGT(manager, Geometry.TYPES.GEOMETRY,Geometry.SUBTYPES.GEOM3DM));
236
        }
237
        return databaseGeometryTypes.get(typeName);
238
    }
239
    
240
}