Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_daldb / src / org / gvsig / fmap / data / feature / db / jdbc / postgresql / PostgresqlStoreUtils.java @ 24491

History | View | Annotate | Download (13.4 KB)

1
package org.gvsig.fmap.data.feature.db.jdbc.postgresql;
2

    
3
import java.sql.Connection;
4
import java.sql.DriverManager;
5
import java.sql.ResultSet;
6
import java.sql.ResultSetMetaData;
7
import java.sql.Statement;
8
import java.util.ArrayList;
9
import java.util.Iterator;
10

    
11
import org.gvsig.fmap.dal.exceptions.DataException;
12
import org.gvsig.fmap.dal.exceptions.InitializeException;
13
import org.gvsig.fmap.dal.exceptions.ReadException;
14
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
15
import org.gvsig.fmap.dal.feature.FeatureType;
16
import org.gvsig.fmap.dal.feature.exceptions.IsNotAttributeSettingException;
17
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureType;
18
import org.gvsig.fmap.data.feature.db.DBAttributeDescriptor;
19
import org.gvsig.fmap.data.feature.db.DBFeatureType;
20
import org.gvsig.fmap.data.feature.db.DBStoreParameters;
21
import org.gvsig.fmap.data.feature.db.jdbc.JDBCDriverNotFoundException;
22
import org.gvsig.fmap.data.feature.db.jdbc.SQLException;
23
import org.gvsig.fmap.geom.Geometry;
24

    
25
public class PostgresqlStoreUtils {
26

    
27
        static String getJDBCUrl(String host, String db, String port) {
28
                String url;
29
                url = "jdbc:postgresql://"+host+":" + port +"/"+db;
30

    
31
                return url;
32
        }
33

    
34
        private static void addConditionForSerialField(DBAttributeDescriptor attr,StringBuffer sqlSeq){
35
                sqlSeq.append(" (");
36
                sqlSeq.append(" column_name = '" + attr.getName() +"'");
37
                sqlSeq.append("  and table_name = '" + attr.getTableName()+ "'");
38
                if (attr.getSchemaName() != null && attr.getSchemaName().length() > 0){
39
                        sqlSeq.append("  and table_schema = '" + attr.getSchemaName() +"'");
40
                }
41

    
42
                sqlSeq.append("  and table_catalog = '" + attr.getCatalogName()+ "'");
43
                sqlSeq.append(")");
44

    
45
        }
46

    
47
        private static void initializeSerialFields(Connection connection,DBFeatureType featureType) throws java.sql.SQLException, DataException{
48
                DBAttributeDescriptor attr;
49

    
50
                ArrayList serialCandidates= new ArrayList();
51
                Iterator iter = featureType.iterator();
52
                while(iter.hasNext()){
53
                        attr = (DBAttributeDescriptor)iter.next();
54
                        if (attr.getSqlTypeName().equals("int4") &&
55
                                        attr.getTableName() != null        &&
56
                                        attr.getTableName().length() > 0){
57
                                serialCandidates.add(attr);
58
                        }
59
                }
60
                if (serialCandidates.size() == 0){
61
                        return;
62
                }
63
                Statement st = connection.createStatement();
64
                StringBuffer sqlSeq= new StringBuffer("select table_catalog,table_schema,table_name,column_name from information_schema.columns where column_default like 'nextval(%'  and ( ");
65
                iter = serialCandidates.iterator();
66
                String sql;
67
                int i;
68
                for (i=0;i<serialCandidates.size()-1;i++){
69
                        attr = (DBAttributeDescriptor)serialCandidates.get(i);
70
                        addConditionForSerialField(attr,sqlSeq);
71
                        sqlSeq.append(" or ");
72
                }
73
                attr = (DBAttributeDescriptor)serialCandidates.get(i);
74
                addConditionForSerialField(attr,sqlSeq);
75

    
76

    
77
                sqlSeq.append(")");
78
                sql=sqlSeq.toString();
79
                ResultSet rs = st.executeQuery(sql);
80
                while (rs.next()){
81
                        iter = serialCandidates.iterator();
82
                        while (iter.hasNext()){
83
                                attr = (DBAttributeDescriptor)iter.next();
84
                                if (rs.getString("column_name").equals(attr.getName())){
85
                                        attr.setAutoIncrement(true);
86
                                        serialCandidates.remove(attr);
87
                                        break;
88
                                }
89
                        }
90

    
91
                }
92

    
93

    
94
        }
95

    
96

    
97
        static DBFeatureType getFeatureType(Connection connection, PostgresqlStoreParameters params) throws ReadException{
98
                DBFeatureType featureType = new DBFeatureType();
99
                String[] ids =params.getFieldsId();
100
                int i;
101
                DBAttributeDescriptor attr;
102

    
103

    
104
                loadFieldsToFeatureType(connection, params, featureType);
105

    
106

    
107

    
108
                try {
109
                        featureType.setFieldsId(ids);
110
                } catch (DataException e) {
111
                        throw new ReadException(PostgresqlStore.DATASTORE_NAME,e);
112
                }
113

    
114
                //Inicializamos los 'serial' ya que en postgres el
115
                //'isAutonumeric' devuelve false
116
//                try{
117
//                        initializeSerialFields(connection,featureType);
118
//                } catch (java.sql.SQLException e) {
119
//                        throw new InitializeException(PostgresqlStore.DATASTORE_NAME,e);
120
//
121
//                }
122
//
123

    
124

    
125
                //Inicializar campos geometricos si los hubiese
126
                //TODO Datos geometricos
127
//                featureType.setDefaultGeometry(params.getGeometryField());
128
                getTableEPSG_and_shapeType(connection,params,featureType);
129

    
130
                //Inicializar la geometria por defecto
131
                if (params.getDefaultGeometryField() != null && params.getDefaultGeometryField() != ""){
132
                        if (featureType.getIndex(params.getDefaultGeometryField())< 0){
133
                                throw new InitializeException(
134
                                                PostgresqlStore.DATASTORE_NAME,
135
                                                new Exception("Geometry Field '"+ params.getDefaultGeometryField() +"' not Found"));
136

    
137
                        }
138
                        attr = (DBAttributeDescriptor)featureType.get(params.getDefaultGeometryField());
139
                        if (attr.getDataType() != FeatureAttributeDescriptor.GEOMETRY){
140
                                throw new InitializeException(
141
                                                PostgresqlStore.DATASTORE_NAME,
142
                                                new Exception("Field '"+ params.getDefaultGeometryField() +"' isn't a geometry"));
143

    
144
                        }
145

    
146

    
147
                }
148
                featureType.setDefaultGeometry(params.getDefaultGeometryField());
149
//                featureType.setGeometryTypes(new int[]{Geometry.TYPES.GEOMETRY});
150

    
151
                return featureType;
152

    
153
        }
154

    
155
        private static void getTableEPSG_and_shapeType(Connection conn,
156
                        DBStoreParameters params, FeatureType featureType) throws ReadException {
157
                try {
158
                        if (params.getDefaultGeometryField() == null
159
                                        || params.getTableName() == null
160
                                        || params.getTableName().length() == 0) {
161
                                return;
162
                        }
163
                        Statement stAux = conn.createStatement();
164

    
165
//                        String sql = "SELECT * FROM GEOMETRY_COLUMNS WHERE F_TABLE_NAME = '"
166
//                                        + getTableName() + "' AND F_GEOMETRY_COLUMN = '" + getLyrDef().getFieldGeometry() + "'";
167
                        String sql;
168
                        if (params.getSchema() == null || params.getSchema().equals("")){
169
                                sql = "SELECT * FROM GEOMETRY_COLUMNS WHERE F_TABLE_SCHEMA = current_schema() AND F_TABLE_NAME = '"
170
                                        + params.getTableName() + "' AND F_GEOMETRY_COLUMN = '" + params.getDefaultGeometryField() + "'";
171
                        }else{
172
                                sql = "SELECT * FROM GEOMETRY_COLUMNS WHERE F_TABLE_SCHEMA = '"+ params.getSchema() + "' AND F_TABLE_NAME = '"
173
                                                + params.getTableName() + "' AND F_GEOMETRY_COLUMN = '" + params.getDefaultGeometryField() + "'";
174
                        }
175

    
176
                        ResultSet rs = stAux.executeQuery(sql);
177
                        rs.next();
178
                        String originalEPSG = "" + rs.getInt("SRID");
179
                        String geometryType = rs.getString("TYPE");
180
                        int shapeType = Geometry.TYPES.GEOMETRY;
181
                        if (geometryType.compareToIgnoreCase("POINT") == 0) {
182
                                shapeType = Geometry.TYPES.POINT;
183
                        } else if (geometryType.compareToIgnoreCase("LINESTRING") == 0) {
184
                                shapeType = Geometry.TYPES.CURVE;
185
                        } else if (geometryType.compareToIgnoreCase("POLYGON") == 0) {
186
                                shapeType = Geometry.TYPES.SURFACE;
187
                        } else if (geometryType.compareToIgnoreCase("MULTIPOINT") == 0) {
188
                                shapeType = Geometry.TYPES.POINT;
189
                        } else if (geometryType.compareToIgnoreCase("MULTILINESTRING") == 0) {
190
                                shapeType = Geometry.TYPES.CURVE;
191
                        } else if (geometryType.compareToIgnoreCase("MULTIPOLYGON") == 0) {
192
                                shapeType = Geometry.TYPES.SURFACE;
193
                        }
194

    
195
                        featureType.setGeometryTypes(new int[]{shapeType});
196
                        featureType.setDefaultSRS(originalEPSG);
197
//                        params.setShapeType(shapeType);
198
                        rs.close();
199
                } catch (java.sql.SQLException e) {
200
                        throw new ReadException(PostgresqlStore.DATASTORE_NAME, e);
201
                }
202

    
203
        }
204

    
205

    
206

    
207
        private static void loadFieldsToFeatureType(Connection conn,PostgresqlStoreParameters params,DBFeatureType featureType) throws ReadException{
208
                String sql="";
209
                String columns=params.getFieldsString();
210
                boolean fillTableData;
211

    
212
                if (params.getSqlSoure() != null){
213
                        sql = params.getSqlSoure();
214
                        fillTableData = false;
215
                } else {
216
                        sql = "Select "+columns+" from " +params.tableID();
217
                        fillTableData = true;
218
                }
219

    
220
                try {
221

    
222
                        Statement stAux = conn.createStatement();
223
                        stAux.setFetchSize(1);
224
                        ResultSet rs = stAux.executeQuery(sql);
225
                        ResultSetMetaData rsMetadata = rs.getMetaData();
226

    
227
                        int i;
228

    
229
                        featureType.setTableID(params.tableID());
230
                        DBAttributeDescriptor attr;
231
                        for (i=1;i<=rsMetadata.getColumnCount();i++){
232
                                attr = getAttributeFromJDBC(featureType,conn,rsMetadata,i);
233
                                featureType.add(attr);
234
//                                attr.setOrdinal(i-1);
235
                                attr.loading();
236
                                attr.setCatalogName(params.getDb());
237
                                if (fillTableData){
238
                                        attr.setSchemaName(params.getSchema());
239
                                        attr.setTableName(params.getTableName());
240

    
241
                                }
242
                                attr.stopLoading();
243
                        }
244
                        rs.close();
245
                        stAux.close();
246

    
247

    
248

    
249
                } catch (java.sql.SQLException e) {
250
                        throw new SQLException(sql,"getFeatureType",e);
251
                } catch (IsNotAttributeSettingException e) {
252
                        e.printStackTrace();
253
                }
254

    
255
        }
256

    
257
        private static DBAttributeDescriptor getAttributeFromJDBC(DefaultFeatureType fType,Connection conn,ResultSetMetaData rsMetadata,int colIndex) throws SQLException{
258
                DBAttributeDescriptor column= (DBAttributeDescriptor) fType.createAttributeDescriptor();
259
                try {
260
                        column.loading();
261
                        column.setName(rsMetadata.getColumnName(colIndex));
262
                        column.setCaseSensitive(rsMetadata.isCaseSensitive(colIndex));
263
                        column.setSqlType(rsMetadata.getColumnType(colIndex));
264
                        column.setAllowNull(rsMetadata.isNullable(colIndex) == ResultSetMetaData.columnNullable);
265
                        column.setAutoIncrement(rsMetadata.isAutoIncrement(colIndex));
266
                        column.setReadOnly(rsMetadata.isReadOnly(colIndex));
267
                        column.setWritable(rsMetadata.isWritable(colIndex));
268
                        column.setClassName(rsMetadata.getColumnClassName(colIndex));
269
                        column.setCatalogName(rsMetadata.getCatalogName(colIndex));
270
                        column.setDefinitelyWritable(rsMetadata.isDefinitelyWritable(colIndex));
271
                        column.setLabel(rsMetadata.getColumnLabel(colIndex));
272
                        column.setSchemaName(rsMetadata.getSchemaName(colIndex));
273
                        column.setTableName(rsMetadata.getTableName(colIndex));
274
                        column.setCatalogName(rsMetadata.getCatalogName(colIndex));
275
                        column.setSqlTypeName(rsMetadata.getColumnTypeName(colIndex));
276
                        column.setSearchable(rsMetadata.isSearchable(colIndex));
277
                        column.setSigned(rsMetadata.isSigned(colIndex));
278
                        column.setCurrency(rsMetadata.isCurrency(colIndex));
279
                        column.setPrecision(rsMetadata.getPrecision(colIndex));
280
                        column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
281

    
282

    
283
                        switch (rsMetadata.getColumnType(colIndex)) {
284
                        case java.sql.Types.INTEGER:
285
                                column.setType(FeatureAttributeDescriptor.INT);
286
                                break;
287
                        case java.sql.Types.BIGINT:
288
                                column.setType(FeatureAttributeDescriptor.LONG);
289
                                break;
290
                        case java.sql.Types.REAL:
291
                                column.setType(FeatureAttributeDescriptor.DOUBLE);
292
                                break;
293
                        case java.sql.Types.DOUBLE:
294
                                column.setType(FeatureAttributeDescriptor.DOUBLE);
295
                                break;
296
                        case java.sql.Types.CHAR:
297
                                column.setType(FeatureAttributeDescriptor.STRING);
298
                                break;
299
                        case java.sql.Types.VARCHAR:
300
                                column.setType(FeatureAttributeDescriptor.STRING);
301
                                break;
302
                        case java.sql.Types.FLOAT:
303
                                column.setType(FeatureAttributeDescriptor.FLOAT);
304
                                break;
305
                        case java.sql.Types.DECIMAL:
306
                                column.setType(FeatureAttributeDescriptor.FLOAT);
307
                                break;
308
                        case java.sql.Types.DATE:
309
                                column.setType(FeatureAttributeDescriptor.DATE);
310
                                break;
311
                        case java.sql.Types.TIME:
312
                                column.setType(FeatureAttributeDescriptor.TIME);
313
                                break;
314
                        case java.sql.Types.TIMESTAMP:
315
                                column.setType(FeatureAttributeDescriptor.TIMESTAMP);
316
                                break;
317
                        case java.sql.Types.BOOLEAN:
318
                                column.setType(FeatureAttributeDescriptor.BOOLEAN);
319
                                break;
320
                        case java.sql.Types.OTHER:
321
                                if (column.getSqlTypeName().equalsIgnoreCase("geometry")){
322
                                        column.setType(FeatureAttributeDescriptor.GEOMETRY);
323
                                        break;
324
                                }
325
                                //No hacemos break para que se quede en default
326

    
327
                        default:
328
                                column.setType(FeatureAttributeDescriptor.OBJECT);
329
                                break;
330
                        }
331
                        column.stopLoading();
332
                } catch (java.sql.SQLException e){
333
                        throw new SQLException("","load attribute definition",e);
334
                } catch (IsNotAttributeSettingException e) {
335
                        e.printStackTrace();
336
                }
337

    
338
                return column;
339

    
340
        }
341

    
342

    
343

    
344

    
345
        static Connection getConnection(String dbUrl, String dbUser, String dbPass) throws InitializeException {
346
                //TODO: Aqu? habria que implementar la llamada
347
                //      al Resource Manager para comprobar si ya hay
348
                //                una connexion a la BD
349
                String connID = getConnectionResourceID(dbUrl, dbUser);
350

    
351
                Connection conn = null;
352
//                IResource res = ResourceManager.getResourceManager().getResource(connID);
353

    
354

    
355

    
356
                try {
357
                        Class.forName("org.postgresql.Driver");
358
                } catch (ClassNotFoundException e) {
359
                        throw new JDBCDriverNotFoundException("org.postgresql.Driver",e);
360
                }
361
                try {
362
                        conn = DriverManager.getConnection(dbUrl, dbUser, dbPass);
363
                        conn.setAutoCommit(false);
364

    
365
                } catch (java.sql.SQLException e1) {
366
                        throw new InitializeException(PostgresqlStore.DATASTORE_NAME,e1);
367
                }
368
                //TODO: Registrar en el Resource manager
369
                // ResourceManager.getResourceManager().addResource(res);
370

    
371
                return conn;
372
        }
373

    
374
        static String getConnectionResourceID(String dbUrl,String dbUser){
375
                return PostgresqlStore.CONNECTION_STRING+";"+dbUrl+";"+dbUser;
376

    
377
        }
378

    
379

    
380

    
381

    
382
        static String addLimitsToSQL(String aSql,int fetchSize,int page){
383
                return aSql+ " limit " + fetchSize + " offset " + (fetchSize*page);
384
        }
385

    
386
        static String getDefaultSchema(Connection conn, String catalog) throws InitializeException {
387
                String sql = "Select current_schema()";
388
                ResultSet rs = null;
389
                Statement st = null;
390
                String schema = null;
391
                try {
392
                        st = conn.createStatement();
393
                        rs = st.executeQuery(sql);
394
                        rs.next();
395
                        schema = rs.getString(1);
396
                } catch (java.sql.SQLException e) {
397
                        throw new InitializeException(PostgresqlStore.DATASTORE_NAME, e);
398
                } finally {
399
                        if (st != null) {
400
                                if (rs != null) {
401
                                        try {
402
                                                rs.close();
403
                                        } catch (java.sql.SQLException e) {
404
                                                throw new InitializeException(
405
                                                                PostgresqlStore.DATASTORE_NAME, e);
406
                                        }
407
                                }
408
                                try {
409
                                        st.close();
410
                                } catch (java.sql.SQLException e) {
411
                                        throw new InitializeException(
412
                                                        PostgresqlStore.DATASTORE_NAME, e);
413
                                }
414

    
415
                        }
416

    
417
                }
418

    
419
                return schema;
420
        }
421

    
422
}
423