Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_daldb / src / org / gvsig / fmap / dal / store / postgresql / PostgreSQLHelper.java @ 38768

History | View | Annotate | Download (21.7 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
* MA  02110-1301, USA.
20
*
21
*/
22

    
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2009 IVER T.I   {{Task}}
26
*/
27

    
28
/**
29
 *
30
 */
31
package org.gvsig.fmap.dal.store.postgresql;
32

    
33
import java.sql.Connection;
34
import java.sql.PreparedStatement;
35
import java.sql.ResultSet;
36
import java.sql.ResultSetMetaData;
37
import java.sql.SQLException;
38
import java.sql.Statement;
39
import java.util.ArrayList;
40
import java.util.Comparator;
41
import java.util.Iterator;
42
import java.util.List;
43
import java.util.Map;
44
import java.util.TreeMap;
45
import java.util.TreeSet;
46

    
47
import org.cresques.cts.IProjection;
48
import org.postgresql.PGResultSetMetaData;
49
import org.slf4j.Logger;
50
import org.slf4j.LoggerFactory;
51

    
52
import org.gvsig.fmap.crs.CRSFactory;
53
import org.gvsig.fmap.dal.DALLocator;
54
import org.gvsig.fmap.dal.DataTypes;
55
import org.gvsig.fmap.dal.NewDataStoreParameters;
56
import org.gvsig.fmap.dal.exception.DataException;
57
import org.gvsig.fmap.dal.exception.InitializeException;
58
import org.gvsig.fmap.dal.exception.ReadException;
59
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
60
import org.gvsig.fmap.dal.feature.EditableFeatureType;
61
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
62
import org.gvsig.fmap.dal.feature.FeatureType;
63
import org.gvsig.fmap.dal.feature.exception.UnsupportedDataTypeException;
64
import org.gvsig.fmap.dal.feature.exception.UnsupportedGeometryException;
65
import org.gvsig.fmap.dal.resource.ResourceAction;
66
import org.gvsig.fmap.dal.resource.spi.ResourceManagerProviderServices;
67
import org.gvsig.fmap.dal.store.jdbc.ConnectionAction;
68
import org.gvsig.fmap.dal.store.jdbc.JDBCHelper;
69
import org.gvsig.fmap.dal.store.jdbc.JDBCHelperUser;
70
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
71
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCException;
72
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecutePreparedSQLException;
73
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecuteSQLException;
74
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCPreparingSQLException;
75
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
76
import org.gvsig.fmap.geom.Geometry;
77
import org.gvsig.fmap.geom.GeometryLocator;
78
import org.gvsig.fmap.geom.GeometryManager;
79
import org.gvsig.fmap.geom.operation.fromwkb.FromWKB;
80
import org.gvsig.fmap.geom.operation.fromwkb.FromWKBGeometryOperationContext;
81
import org.gvsig.fmap.geom.primitive.Envelope;
82
import org.gvsig.tools.ToolsLocator;
83
import org.gvsig.tools.exception.BaseException;
84

    
85
/**
86
 * @author jmvivo
87
 *
88
 */
89
public class PostgreSQLHelper extends JDBCHelper {
90

    
91
        private static Logger logger = LoggerFactory
92
                        .getLogger(PostgreSQLHelper.class);
93

    
94
        private Map pgSR2SRSID = new TreeMap();
95
        private Map srsID2pgSR = new TreeMap();
96

    
97

    
98
        PostgreSQLHelper(JDBCHelperUser consumer,
99
                        PostgreSQLConnectionParameters params)
100
                        throws InitializeException {
101

    
102
                super(consumer, params);
103
        }
104

    
105
        protected void initializeResource() throws InitializeException {
106
                ResourceManagerProviderServices manager = (ResourceManagerProviderServices) DALLocator
107
                .getResourceManager();
108
                PostgreSQLResource resource = (PostgreSQLResource) manager
109
                .createAddResource(
110
                                PostgreSQLResource.NAME, new Object[] {
111
                                                params.getUrl(), params.getHost(),
112
                                                params.getPort(), params.getDBName(), params.getUser(),
113
                                                params.getPassword(),
114
                                                params.getJDBCDriverClassName(),
115
                                                ((PostgreSQLConnectionParameters) params).getUseSSL() });
116
                this.setResource(resource);
117
        }
118

    
119

    
120
        protected String getDefaultSchema(Connection conn)
121
                        throws JDBCException {
122
                if (defaultSchema == null) {
123
                        String sql = "Select current_schema()";
124
                        ResultSet rs = null;
125
                        Statement st = null;
126
                        String schema = null;
127
                        try {
128
                                st = conn.createStatement();
129
                                try {
130
                                        rs = st.executeQuery(sql);
131
                                } catch (java.sql.SQLException e) {
132
                                        throw new JDBCExecuteSQLException(sql, e);
133
                                }
134
                                rs.next();
135
                                schema = rs.getString(1);
136
                        } catch (java.sql.SQLException e) {
137
                                throw new JDBCSQLException(e);
138
                        } finally {
139
                                try {rs.close();} catch (Exception e) {logger.error("Exception clossing resulset", e);};
140
                                try {st.close();} catch (Exception e) {logger.error("Exception clossing statement", e);};
141
                                rs = null;
142
                                st = null;
143
                        }
144
                        defaultSchema = schema;
145
                }
146

    
147
                return defaultSchema;
148
        }
149

    
150
        public Envelope getFullEnvelopeOfField(
151
                        JDBCStoreParameters storeParams,
152
                        String geometryAttrName, Envelope limit)
153
                        throws DataException {
154

    
155
                StringBuilder strb = new StringBuilder();
156
                strb.append("Select asbinary(extent(");
157
                strb.append(escapeFieldName(geometryAttrName));
158
                strb.append(")) from ");
159

    
160
                if (storeParams.getSQL() != null
161
                                && storeParams.getSQL().trim().length() == 0) {
162
                        strb.append('(');
163
                        strb.append(storeParams.getSQL());
164
                        strb.append(") as __extentfield__ ");
165
                } else {
166
                        strb.append(storeParams.tableID());
167
                }
168

    
169

    
170
                if (limit != null){
171
                        strb.append(" where  intersects(GeomFromText('");
172
                        strb.append(limit.toString());
173
                        strb.append("')), envelope(");
174
                        strb.append(escapeFieldName(geometryAttrName));
175
                        strb.append(")) ");
176
                }
177

    
178
                final String sql = strb.toString();
179

    
180
                GeometryManager geoMan = GeometryLocator.getGeometryManager();
181

    
182
                this.open();
183

    
184
                return (Envelope) getResource().execute(new ResourceAction() {
185
                        public Object run() throws Exception {
186
                                ResultSet rs = null;
187
                                Statement st = null;
188
                                String schema = null;
189
                                Connection conn = null;
190
                                Envelope fullEnvelope = null;
191
                                try {
192

    
193
                                        conn = getConnection();
194
                                        st = conn.createStatement();
195
                                        try {
196
                                                rs = st.executeQuery(sql);
197
                                        } catch (java.sql.SQLException e) {
198
                                                throw new JDBCExecuteSQLException(sql, e);
199
                                        }
200
                                        if (!rs.next()) {
201
                                                return null;
202
                                        }
203

    
204
                                        byte[] data = rs.getBytes(1);
205
                                        if (data == null) {
206
                                                return null;
207
                                        }
208
                                        initializeFromWKBOperation();
209
                                        fromWKBContext.setData(data);
210
                                        Geometry geom =
211
                                                        (Geometry) fromWKB.invoke(null, fromWKBContext);
212

    
213
                                        fullEnvelope = geom.getEnvelope();
214

    
215
                                        return fullEnvelope;
216
                                } catch (java.sql.SQLException e) {
217
                                        throw new JDBCSQLException(e);
218
                                } catch (BaseException e) {
219
                                        throw new ReadException(user.getProviderName(), e);
220
                                } finally {
221
                                        try {
222
                                                rs.close();
223
                                        } catch (Exception e) {
224
                                        }
225
                                        try {
226
                                                st.close();
227
                                        } catch (Exception e) {
228
                                        }
229
                                        try {
230
                                                conn.close();
231
                                        } catch (Exception e) {
232
                                        }
233
                                        rs = null;
234
                                        st = null;
235
                                        conn = null;
236
                                }
237
                        }
238
                });
239
        }
240

    
241
        @Override
242
        protected boolean supportsGeometry() {
243
                return true;
244
        }
245

    
246
        /**
247
         * Fill <code>featureType</code> geometry attributes with SRS and ShapeType
248
         * information stored in the table GEOMETRY_COLUMNS
249
         *
250
         * @param conn
251
         * @param rsMetadata
252
         * @param featureType
253
         * @throws ReadException
254
         */
255
        protected void loadSRS_and_shapeType(Connection conn,
256
                        ResultSetMetaData rsMetadata, EditableFeatureType featureType,
257
                        String baseSchema, String baseTable)
258
                        throws JDBCException {
259

    
260
                Statement st = null;
261
                ResultSet rs = null;
262
                try {
263
                        // Sacamos la lista de los attributos geometricos
264
                        EditableFeatureAttributeDescriptor attr;
265
                        List geoAttrs = new ArrayList();
266

    
267
                        Iterator iter = featureType.iterator();
268
                        while (iter.hasNext()) {
269
                                attr = (EditableFeatureAttributeDescriptor) iter.next();
270
                                if (attr.getType() == DataTypes.GEOMETRY) {
271
                                        geoAttrs.add(attr);
272
                                }
273
                        }
274
                        if (geoAttrs.size() < 1) {
275
                                return;
276
                        }
277

    
278

    
279
                        // preparamos un set con las lista de tablas de origen
280
                        // de los campos
281
                        class TableId {
282
                                public String schema=null;
283
                                public String table=null;
284
                                public String field = null;
285

    
286
                                public void appendToSQL(StringBuilder strb) {
287
                                        if (schema == null || schema.length() == 0) {
288
                                                strb
289
                                                                .append("( F_TABLE_SCHEMA = current_schema() AND F_TABLE_NAME = '");
290
                                        } else {
291
                                                strb.append("( F_TABLE_SCHEMA = '");
292
                                                strb.append(schema);
293
                                                strb.append("' AND F_TABLE_NAME = '");
294
                                        }
295
                                        strb.append(table);
296
                                        strb.append("' AND F_GEOMETRY_COLUMN = '");
297
                                        strb.append(field);
298
                                        strb.append("' )");
299
                                }
300

    
301
                        }
302
                        Comparator cmp = new Comparator(){
303
                                public int compare(Object arg0, Object arg1) {
304
                                        TableId a0 = (TableId) arg0;
305
                                        TableId a1 = (TableId) arg1;
306

    
307
                                        if (!a0.field.equals(a1.field)) {
308
                                                return -1;
309
                                        }
310
                                        if (!a0.table.equals(a1.table)) {
311
                                                return -1;
312
                                        }
313
                                        if (!a0.schema.equals(a1.schema)) {
314
                                                return -1;
315
                                        }
316
                                        return 0;
317
                                }
318
                        };
319
                        TreeSet set = new TreeSet(cmp);
320
                        TableId tableId;
321
                        iter = geoAttrs.iterator();
322
                        int rsIndex;
323
                        while (iter.hasNext()) {
324
                                attr = (EditableFeatureAttributeDescriptor) iter.next();
325
                                tableId = new TableId();
326
                                rsIndex = attr.getIndex() + 1;
327

    
328
                                if (baseSchema == null && baseTable == null) {
329
                                        if (rsMetadata instanceof PGResultSetMetaData) {
330
                                                tableId.schema = ((PGResultSetMetaData) rsMetadata)
331
                                                                .getBaseSchemaName(rsIndex);
332
                                                tableId.table = ((PGResultSetMetaData) rsMetadata)
333
                                                                .getBaseTableName(rsIndex);
334
                                                tableId.field = ((PGResultSetMetaData) rsMetadata)
335
                                                                .getBaseColumnName(rsIndex);
336

    
337
                                        } else {
338
                                                tableId.schema = rsMetadata.getSchemaName(rsIndex);
339
                                                tableId.table = rsMetadata.getTableName(rsIndex);
340
                                                tableId.field = rsMetadata.getColumnName(rsIndex);
341
                                        }
342
                                } else {
343
                                        tableId.schema = baseSchema;
344
                                        tableId.table = baseTable;
345
                                        tableId.field = rsMetadata.getColumnName(rsIndex);
346
                                }
347
                                if (tableId.table == null || tableId.table.length() == 0) {
348
                                        // Si no tiene tabla origen (viene de algun calculo por ej.)
349
                                        // lo saltamos ya que no estara en la tabla GEOMETRY_COLUMNS
350
                                        continue;
351
                                }
352
                                set.add(tableId);
353
                        }
354

    
355
                        if (set.size() == 0) {
356
                                return;
357
                        }
358

    
359
                        // Preparamos una sql para que nos saque el resultado
360
                        StringBuilder strb = new StringBuilder();
361
                        strb.append("Select geometry_columns.*,auth_name || ':' || auth_srid as SRSID ");
362
                        strb.append("from geometry_columns left join spatial_ref_sys on ");
363
                        strb.append("geometry_columns.srid = spatial_ref_sys.srid WHERE ");
364
                        iter = set.iterator();
365
                        for (int i=0;i<set.size()-1;i++) {
366
                                tableId = (TableId) iter.next();
367
                                tableId.appendToSQL(strb);
368
                                strb.append(" OR ");
369
                        }
370
                        tableId = (TableId) iter.next();
371
                        tableId.appendToSQL(strb);
372
                        String sql = strb.toString();
373

    
374

    
375
                        st = conn.createStatement();
376
                        try {
377
                                rs = st.executeQuery(sql);
378
                        } catch (SQLException e) {
379
                                throw new JDBCExecuteSQLException(sql, e);
380
                        }
381
                        String srsID;
382
                        int pgSrid;
383
                        int geometryType;
384
                        int geometrySubtype;
385
                        String geomTypeStr;
386
                        int dimensions;
387
                        IProjection srs;
388

    
389
                        while (rs.next()){
390
                                srsID = rs.getString("SRSID");
391
                                pgSrid = rs.getInt("SRID");
392
                                geomTypeStr = rs.getString("TYPE").toUpperCase();
393
                                geometryType = Geometry.TYPES.GEOMETRY;
394
                                if (geomTypeStr.startsWith("POINT")) {
395
                                        geometryType = Geometry.TYPES.POINT;
396
                                } else if (geomTypeStr.startsWith("LINESTRING")) {
397
                                        geometryType = Geometry.TYPES.CURVE;
398
                                } else if (geomTypeStr.startsWith("POLYGON")) {
399
                                        geometryType = Geometry.TYPES.SURFACE;
400
                                } else if (geomTypeStr.startsWith("MULTIPOINT")) {
401
                                        geometryType = Geometry.TYPES.MULTIPOINT;
402
                                } else if (geomTypeStr.startsWith("MULTILINESTRING")) {
403
                                        geometryType = Geometry.TYPES.MULTICURVE;
404
                                } else if (geomTypeStr.startsWith("MULTIPOLYGON")) {
405
                                        geometryType = Geometry.TYPES.MULTISURFACE;
406
                                }
407
                                dimensions = rs.getInt("coord_dimension");
408
                                geometrySubtype = Geometry.SUBTYPES.GEOM2D;
409
                                if (dimensions > 2) {
410
                                        if (dimensions == 3) {
411
                                                if (geomTypeStr.endsWith("M")) {
412
                                                        geometrySubtype = Geometry.SUBTYPES.GEOM2DM;
413
                                                } else {
414
                                                        geometrySubtype = Geometry.SUBTYPES.GEOM3D;
415
                                                }
416

    
417
                                        } else {
418
                                                geometrySubtype = Geometry.SUBTYPES.GEOM3DM;
419
                                        }
420
                                }
421
                                addToPgSRToSRSID(pgSrid, srsID);
422

    
423

    
424
                                iter = geoAttrs.iterator();
425
                                while (iter.hasNext()) {
426
                                        attr = (EditableFeatureAttributeDescriptor) iter.next();
427
                                        rsIndex = attr.getIndex() + 1;
428
                                        if (!rsMetadata.getColumnName(rsIndex).equals(
429
                                                        rs.getString("f_geometry_column"))) {
430
                                                continue;
431
                                        }
432

    
433
                                        if (baseSchema == null && baseTable == null) {
434

    
435
                                                if (rsMetadata instanceof PGResultSetMetaData) {
436
                                                        if (!((PGResultSetMetaData) rsMetadata)
437
                                                                        .getBaseTableName(rsIndex).equals(
438
                                                                                        rs.getString("f_table_name"))) {
439
                                                                continue;
440
                                                        }
441
                                                        String curSchema = rs.getString("f_table_schema");
442
                                                        String metaSchema = ((PGResultSetMetaData) rsMetadata)
443
                                                                        .getBaseSchemaName(rsIndex);
444
                                                        if (!metaSchema.equals(curSchema)) {
445
                                                                if (metaSchema.length() == 0
446
                                                                                && metaSchema == getDefaultSchema(conn)) {
447
                                                                } else {
448
                                                                        continue;
449
                                                                }
450
                                                        }
451

    
452
                                                } else {
453

    
454
                                                        if (!rsMetadata.getTableName(rsIndex).equals(
455
                                                                        rs.getString("f_table_name"))) {
456
                                                                continue;
457
                                                        }
458
                                                        String curSchema = rs.getString("f_table_schema");
459
                                                        String metaSchema = rsMetadata
460
                                                                        .getSchemaName(rsIndex);
461
                                                        if (!metaSchema.equals(curSchema)) {
462
                                                                if (metaSchema.length() == 0
463
                                                                                && metaSchema == getDefaultSchema(conn)) {
464
                                                                } else {
465
                                                                        continue;
466
                                                                }
467
                                                        }
468
                                                }
469
                                        }
470
                                        attr.setGeometryType(geometryType);
471
                                        attr.setGeometrySubType(geometrySubtype);
472
                                        if (srsID != null && srsID.length() > 0) {
473
                                                attr.setSRS(CRSFactory.getCRS(srsID));
474
                                        }
475
                                        iter.remove();
476
                                }
477
                                iter = geoAttrs.iterator();
478
                                while (iter.hasNext()) {
479
                                        attr = (EditableFeatureAttributeDescriptor) iter.next();
480
                                        attr.setSRS(null);
481
                                        attr.setGeometryType(Geometry.TYPES.GEOMETRY);
482

    
483
                                }
484
                        }
485

    
486
                } catch (java.sql.SQLException e) {
487
                        throw new JDBCSQLException(e);
488
                } finally {
489
                        try {rs.close();} catch (Exception e) {        };
490
                        try {st.close();} catch (Exception e) {        };
491
                }
492

    
493
        }
494

    
495

    
496
        public String getSqlColumnTypeDescription(FeatureAttributeDescriptor attr) {
497
                if (attr.getType() == DataTypes.GEOMETRY) {
498
                        return "geometry";
499
                }
500
                return super.getSqlColumnTypeDescription(attr);
501
        }
502

    
503

    
504
        public int getPostgisGeomDimensions(int geometrySubType) {
505
                switch (geometrySubType) {
506
                case Geometry.SUBTYPES.GEOM2D:
507
                        return 2;
508
                case Geometry.SUBTYPES.GEOM2DM:
509
                case Geometry.SUBTYPES.GEOM3D:
510
                        return 3;
511

    
512
                case Geometry.SUBTYPES.GEOM3DM:
513
                        return 4;
514
                default:
515
                        throw new UnsupportedDataTypeException(
516
                                        ToolsLocator.getDataTypesManager().getTypeName(DataTypes.GEOMETRY),
517
                                        DataTypes.GEOMETRY);
518
                }
519
        }
520

    
521
        public String getPostgisGeomType(int geometryType, int geometrySubType) {
522
                String pgGeomType;
523
                switch (geometryType) {
524
                case Geometry.TYPES.GEOMETRY:
525
                        pgGeomType = "GEOMETRY";
526
                        break;
527
                case Geometry.TYPES.POINT:
528
                        pgGeomType = "POINT";
529
                        break;
530
                case Geometry.TYPES.CURVE:
531
                        pgGeomType = "LINESTRING";
532
                        break;
533
                case Geometry.TYPES.SURFACE:
534
                        pgGeomType = "POLYGON";
535
                        break;
536
                case Geometry.TYPES.MULTIPOINT:
537
                        pgGeomType = "MULTIPOINT";
538
                        break;
539
                case Geometry.TYPES.MULTICURVE:
540
                        pgGeomType = "MULTILINESTRING";
541
                        break;
542
                case Geometry.TYPES.MULTISURFACE:
543
                        pgGeomType = "MULTIPOLYGON";
544
                        break;
545
                default:
546
                        throw new UnsupportedGeometryException(geometryType,
547
                                        geometrySubType);
548
                }
549
                if (geometrySubType == Geometry.SUBTYPES.GEOM2DM
550
                                || geometrySubType == Geometry.SUBTYPES.GEOM3DM) {
551
                        pgGeomType = pgGeomType + "M";
552
                } else if (geometrySubType == Geometry.SUBTYPES.GEOM3D) {
553
                        throw new UnsupportedGeometryException(geometryType,
554
                                        geometrySubType);
555
                }
556
                return pgGeomType;
557
        }
558

    
559
        public int getProviderSRID(String srs) {
560
                if (srs != null) {
561
                        Integer pgSRID = (Integer) srsID2pgSR.get(srs);
562
                        if (pgSRID != null) {
563
                                return pgSRID.intValue();
564
                        }
565

    
566
                        return searchpgSRID(srs);
567

    
568
                }
569
                return -1;
570
        }
571

    
572

    
573
        public int getProviderSRID(IProjection srs) {
574
                if (srs != null) {
575
                        Integer pgSRID = (Integer) srsID2pgSR.get(srs.getAbrev());
576
                        if (pgSRID != null) {
577
                                return pgSRID.intValue();
578
                        }
579

    
580
                        return searchpgSRID(srs);
581

    
582
                }
583
                return -1;
584
        }
585

    
586
        private int searchpgSRID(final IProjection srs) {
587
                if (srs == null) {
588
                        return -1;
589
                }
590
                return searchpgSRID(srs.getAbrev());
591
        }
592

    
593
        private int searchpgSRID(final String srsID) {
594
                if (srsID == null) {
595
                        return -1;
596
                }
597

    
598
                ConnectionAction action = new ConnectionAction(){
599

    
600
                        public Object action(Connection conn) throws DataException {
601

    
602
                                String[] abrev = srsID.split(":");
603
                                StringBuilder sqlb = new StringBuilder();
604
                                sqlb.append("select srid from spatial_ref_sys where ");
605
                                if (abrev.length > 1) {
606
                                        sqlb.append("auth_name = ? and ");
607
                                }
608
                                sqlb.append("auth_srid = ?");
609

    
610
                                String sql = sqlb.toString();
611
                                PreparedStatement st;
612
                                try {
613
                                        st = conn.prepareStatement(sql);
614
                                } catch (SQLException e){
615
                                        throw new JDBCPreparingSQLException(sql,e);
616
                                }
617
                                ResultSet rs = null;
618
                                try{
619
                                        int i=0;
620
                                        if (abrev.length > 1){
621
                                                st.setString(i+1, abrev[i]);
622
                                                i++;
623
                                        }
624
                                        st.setInt(i + 1, Integer.parseInt(abrev[i]));
625

    
626
                                        try{
627
                                                rs = st.executeQuery();
628
                                        } catch (SQLException e){
629
                                                throw new JDBCExecutePreparedSQLException(sql, abrev, e);
630
                                        }
631

    
632
                                        if (!rs.next()) {
633
                                                return null;
634
                                        }
635

    
636
                                        return new Integer(rs.getInt(1));
637

    
638
                                } catch (SQLException e){
639
                                        throw new JDBCSQLException(e);
640
                                } finally{
641
                                        try {rs.close(); } catch (Exception e) {};
642
                                        try {st.close(); } catch (Exception e) {};
643
                                }
644

    
645
                        }
646

    
647
                };
648

    
649
                Integer pgSRSID = null;
650
                try {
651
                        pgSRSID = (Integer) doConnectionAction(action);
652
                } catch (Exception e) {
653
                        logger.error("Excetion searching pgSRS", e);
654
                        return -1;
655
                }
656

    
657
                if (pgSRSID != null) {
658
                        addToPgSRToSRSID(pgSRSID.intValue(), srsID);
659
                        return pgSRSID.intValue();
660
                }
661
                return -1;
662

    
663
        }
664

    
665
        private void addToPgSRToSRSID(int pgSRID, String srsId) {
666
                if (pgSRID < 0 || srsId == null || srsId.length() == 0) {
667
                        return;
668
                }
669
                Integer pgSRIDInteger = new Integer(pgSRID);
670
                pgSR2SRSID.put(pgSRIDInteger, srsId);
671
                srsID2pgSR.put(srsId, pgSRIDInteger);
672
        }
673

    
674
        public List<String> getSqlGeometyFieldAdd(FeatureAttributeDescriptor attr,
675
                        String table, String schema) {
676
                // SELECT AddGeometryColumn({schema}, {table}, {field}, {srid}(int),
677
                // {geomType}(Str), {dimensions}(int))
678

    
679
                // gemoType:
680
                /*
681
                 * POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING,
682
                 * MULTIPOLYGON, GEOMETRYCOLLECTION POINTM, LINESTRINGM, POLYGONM,
683
                 * MULTIPOINTM, MULTILINESTRINGM, MULTIPOLYGONM, GEOMETRYCOLLECTIONM
684
                 */
685

    
686
                List<String> sqls = new ArrayList<String>();
687

    
688
                StringBuilder strb = new StringBuilder();
689
                strb.append("SELECT AddGeometryColumn('");
690
                if (schema != null && schema.length() > 0) {
691
                        strb.append(schema);
692
                        strb.append("', '");
693
                }
694
                strb.append(table);
695
                strb.append("', '");
696
                strb.append(attr.getName().toLowerCase());
697
                strb.append("', ");
698
                // strb.append("-1");
699
                strb.append(getProviderSRID(attr.getSRS()));
700
                strb.append(", '");
701
                
702
                // ===========================================================================
703
            // TODO Improve this. Keep in mind that MULTIPOLYGON will not accept POLYGON
704
        strb.append("GEOMETRY");
705
                /*
706
                strb.append(getPostgisGeomType(attr.getGeometryType(), attr
707
                                .getGeometrySubType()));
708
                                */
709
        // ===========================================================================
710
                strb.append("', ");
711
                strb.append(getPostgisGeomDimensions(attr.getGeometrySubType()));
712
                strb.append(")");
713

    
714

    
715
                sqls.add(strb.toString());
716

    
717
                /*ALTER TABLE muni10000_peq_test DROP CONSTRAINT enforce_srid_the_geom;*/
718
                /*
719
                strb = new StringBuilder();
720
                strb.append("Alter table ");
721
                if (schema != null && schema.length() > 0) {
722
                        strb.append(schema);
723
                        strb.append(".");
724
                }
725
                strb.append("f_table_name = '");
726
                strb.append(table);
727
                strb.append("' AND f_geometry_column = '");
728
                strb.append(attr.getName());
729
                strb.append("' AND srid = -1");
730

731

732
                sqls.add(strb.toString());
733
                */
734
                return sqls;
735
        }
736

    
737
        public String getSqlFieldName(FeatureAttributeDescriptor attribute) {
738
                if (attribute.getType() == DataTypes.GEOMETRY) {
739
                        return "asBinary(" + super.getSqlFieldName(attribute) + ")";
740
                }
741
                return super.getSqlFieldName(attribute);
742
        }
743

    
744
        protected EditableFeatureAttributeDescriptor createAttributeFromJDBC(
745
                        EditableFeatureType type, Connection conn,
746
                        ResultSetMetaData rsMetadata, int colIndex) throws SQLException {
747
                if (rsMetadata.getColumnType(colIndex) == java.sql.Types.OTHER) {
748
                        if (rsMetadata.getColumnTypeName(colIndex).equalsIgnoreCase(
749
                                        "geometry")) {
750
                                return type.add(rsMetadata.getColumnName(colIndex),
751
                                                DataTypes.GEOMETRY);
752

    
753
                        }
754
                }
755

    
756
                return super.createAttributeFromJDBC(type, conn, rsMetadata, colIndex);
757
        }
758

    
759
        public List getAdditionalSqlToCreate(NewDataStoreParameters ndsp,
760
                        FeatureType fType) {
761
                FeatureAttributeDescriptor attr;
762
                Iterator iter = fType.iterator();
763
                List result = new ArrayList();
764
                PostgreSQLNewStoreParameters pgNdsp = (PostgreSQLNewStoreParameters) ndsp;
765
                while (iter.hasNext()){
766
                        attr = (FeatureAttributeDescriptor) iter.next();
767
                        if (attr.getType() == DataTypes.GEOMETRY){
768
                                result.addAll(getSqlGeometyFieldAdd(attr, pgNdsp.getTable(),
769
                                                pgNdsp
770
                                                .getSchema()));
771
                        }
772
                }
773

    
774
                return result;
775
        }
776

    
777
        public String getSqlFieldDescription(FeatureAttributeDescriptor attr)
778
                        throws DataException {
779
                if (attr.getType() == DataTypes.GEOMETRY){
780
                        return null;
781
                }
782
                return super.getSqlFieldDescription(attr);
783
        }
784

    
785

    
786
        public boolean allowAutomaticValues() {
787
                return Boolean.TRUE;
788
        }
789

    
790
        public boolean supportOffset() {
791
                return true;
792
        }
793

    
794
        public boolean supportsUnion() {
795
                return true;
796
        }
797

    
798
}