Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_daldb / src / org / gvsig / fmap / dal / store / postgresql / PostgreSQLHelper.java @ 28678

History | View | Annotate | Download (37.4 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.Arrays;
41
import java.util.Comparator;
42
import java.util.Iterator;
43
import java.util.List;
44
import java.util.Map;
45
import java.util.TreeMap;
46
import java.util.TreeSet;
47

    
48
import org.cresques.cts.IProjection;
49
import org.gvsig.fmap.crs.CRSFactory;
50
import org.gvsig.fmap.dal.DALLocator;
51
import org.gvsig.fmap.dal.DataTypes;
52
import org.gvsig.fmap.dal.exception.CloseException;
53
import org.gvsig.fmap.dal.exception.DataException;
54
import org.gvsig.fmap.dal.exception.InitializeException;
55
import org.gvsig.fmap.dal.exception.OpenException;
56
import org.gvsig.fmap.dal.exception.ReadException;
57
import org.gvsig.fmap.dal.exception.WriteException;
58
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
59
import org.gvsig.fmap.dal.feature.EditableFeatureType;
60
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
61
import org.gvsig.fmap.dal.feature.FeatureType;
62
import org.gvsig.fmap.dal.feature.exception.UnsupportedDataTypeException;
63
import org.gvsig.fmap.dal.feature.exception.UnsupportedGeometryException;
64
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
65
import org.gvsig.fmap.dal.resource.exception.ResourceBeginException;
66
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
67
import org.gvsig.fmap.dal.resource.spi.ResourceManagerProviderServices;
68
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
69
import org.gvsig.fmap.dal.store.jdbc.JDBCException;
70
import org.gvsig.fmap.dal.store.jdbc.JDBCExecutePreparedSQLException;
71
import org.gvsig.fmap.dal.store.jdbc.JDBCExecuteSQLException;
72
import org.gvsig.fmap.dal.store.jdbc.JDBCPreparingSQLException;
73
import org.gvsig.fmap.dal.store.jdbc.JDBCSQLException;
74
import org.gvsig.fmap.dal.store.jdbc.JDBCTransactionCommitException;
75
import org.gvsig.fmap.dal.store.jdbc.JDBCTransactionRollbackException;
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.operation.towkb.ToWKB;
82
import org.gvsig.fmap.geom.operation.towkb.ToWKBOperationContext;
83
import org.gvsig.fmap.geom.primitive.Envelope;
84
import org.gvsig.tools.exception.BaseException;
85
import org.postgresql.PGResultSetMetaData;
86
import org.slf4j.Logger;
87
import org.slf4j.LoggerFactory;
88

    
89
/**
90
 * @author jmvivo
91
 *
92
 */
93
class PostgreSQLHelper implements ResourceConsumer {
94

    
95
        private static Logger logger = LoggerFactory
96
                        .getLogger(PostgreSQLHelper.class);
97

    
98
        private PostgreSQLConnectionParameters params;
99
        private PostgreSQLResource resource;
100
        private PostgreSQLHelperUser user;
101
        private boolean isOpen;
102
        private String name;
103

    
104
        private Map pgSR2SRSID = new TreeMap();
105
        private Map srsID2pgSR = new TreeMap();
106

    
107
        private String defaultSchema;
108

    
109
        private FromWKB fromWKB = null;
110
        private FromWKBGeometryOperationContext fromWKBContext = null;
111
        private ToWKBOperationContext toWKBContext = new ToWKBOperationContext();
112

    
113
        PostgreSQLHelper(PostgreSQLHelperUser consumer,
114
                        PostgreSQLConnectionParameters params)
115
                        throws InitializeException {
116

    
117
                this.user = consumer;
118
                this.name = user.getName();
119
                this.params = params;
120

    
121
                ResourceManagerProviderServices manager = (ResourceManagerProviderServices) DALLocator
122
                                .getResourceManager();
123
                resource = (PostgreSQLResource) manager.createResource(
124
                                PostgreSQLResource.NAME, new Object[] { params.getHost(),
125
                                                params.getPort(), params.getDBName(), params.getUser(),
126
                                                params.getPassword(),
127
                                                PostgreSQLLibrary.DEFAULT_JDCB_DRIVER_NAME,
128
                                                params.getUseSSL() });
129
                resource.addConsumer(this);
130

    
131
        }
132

    
133
        /* (non-Javadoc)
134
         * @see org.gvsig.fmap.dal.resource.spi.ResourceConsumer#closeResourceRequested(org.gvsig.fmap.dal.resource.spi.ResourceProvider)
135
         */
136
        public boolean closeResourceRequested(ResourceProvider resource) {
137
                return user.closeResourceRequested(resource);
138
        }
139

    
140
        /* (non-Javadoc)
141
         * @see org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.gvsig.fmap.dal.resource.spi.ResourceProvider)
142
         */
143
        public void resourceChanged(ResourceProvider resource) {
144
                user.resourceChanged(resource);
145

    
146
        }
147

    
148
        /**
149
         * open the resource
150
         *
151
         * @return true if the resourse was open in this call
152
         * @throws OpenException
153
         */
154
        public boolean open() throws OpenException {
155
                if (isOpen) {
156
                        return false;
157
                }
158
                try {
159
                        begin();
160
                } catch (ResourceBeginException e1) {
161
                        throw new OpenException(name, e1);
162
                }
163
                try {
164
                        resource.connect();
165
                        resource.notifyOpen();
166

    
167
                        this.user.opendDone();
168

    
169
                        isOpen = true;
170

    
171
                        return true;
172
                } catch (DataException e) {
173
                        throw new OpenException(name, e);
174
                } finally {
175
                        end();
176
                }
177

    
178
        }
179

    
180
        public void close() throws CloseException {
181
                if (!isOpen) {
182
                        return;
183
                }
184
                try {
185
                        begin();
186
                } catch (ResourceBeginException e) {
187
                        throw new CloseException(name, e);
188
                }
189
                try {
190

    
191
                        isOpen = false;
192

    
193
                        resource.notifyClose();
194
                        this.user.closeDone();
195
                } catch (DataException e) {
196
                        throw new CloseException(this.name, e);
197
                } finally {
198
                        end();
199
                }
200
        }
201

    
202
        public void end() {
203
                resource.end();
204
        }
205

    
206
        public void begin() throws ResourceBeginException {
207
                this.resource.begin();
208
        }
209

    
210
        public Connection getConnection() throws AccessResourceException {
211
                return resource.getJDBCConnection();
212

    
213
        }
214

    
215
        public void dispose() {
216
                resource.removeConsumer(this);
217
        }
218

    
219
        public void loadFeatureType(EditableFeatureType featureType,
220
                        PostgreSQLStoreParameters storeParams) throws DataException {
221
                if (storeParams.getSQL() != null && storeParams.getSQL().trim().length() == 0) {
222
                        loadFeatureType(featureType, storeParams, storeParams.getSQL(),
223
                                        null, null);
224
                } else {
225
                        String sql = "Select * from " + storeParams.tableID()
226
                                        + " where false";
227
                        loadFeatureType(featureType, storeParams, sql, storeParams
228
                                        .getSchema(), storeParams.getTable());
229
                }
230
        }
231

    
232

    
233
        public void loadFeatureType(EditableFeatureType featureType,
234
                        PostgreSQLStoreParameters storeParams, String sql, String schema,
235
                        String table)
236
                        throws DataException {
237
                Connection conn = null;
238
                this.open();
239
                this.begin();
240
                try{
241
                        conn = getConnection();
242

    
243
                        String[] pks = storeParams.getPkFields();
244
                        if (pks == null || pks.length < 1) {
245
                                if (storeParams.getTable() != null
246
                                        && storeParams.getTable().trim().length() > 0) {
247
                                        pks = getPksFrom(conn, storeParams);
248

    
249
                                }
250
                        }
251

    
252
                        loadFeatureType(conn, featureType, sql, pks,
253
                                        storeParams
254
                                .getDefaultGeometry(), schema, table);
255

    
256

    
257
                } finally{
258
                        try {conn.close();} catch (Exception e){};
259
                        this.end();
260
                }
261
        }
262

    
263
        private String[] getPksFrom(Connection conn,
264
                        PostgreSQLStoreParameters params) throws JDBCException {
265
                Statement st;
266
                StringBuffer sql = new StringBuffer();
267
                ResultSet rs;
268
                ArrayList list = new ArrayList();
269
                /*
270
                 * SELECT column_name FROM INFORMATION_SCHEMA.constraint_column_usage
271
                 * left join INFORMATION_SCHEMA.table_constraints on
272
                 * (INFORMATION_SCHEMA.table_constraints.constraint_name =
273
                 * INFORMATION_SCHEMA.constraint_column_usage.constraint_name and
274
                 * INFORMATION_SCHEMA.table_constraints.table_name =
275
                 * INFORMATION_SCHEMA.constraint_column_usage.table_name and
276
                 * INFORMATION_SCHEMA.table_constraints.table_schema =
277
                 * INFORMATION_SCHEMA.constraint_column_usage.table_schema) WHERE
278
                 * INFORMATION_SCHEMA.constraint_column_usage.table_name like
279
                 * 'muni10000_peq' AND
280
                 * INFORMATION_SCHEMA.constraint_column_usage.table_schema like 'public'
281
                 * AND INFORMATION_SCHEMA.constraint_column_usage.table_catalog like
282
                 * 'gis' AND constraint_type='PRIMARY KEY'
283
                 */
284

    
285
                sql.append("SELECT column_name FROM INFORMATION_SCHEMA.constraint_column_usage ");
286
                sql.append("left join INFORMATION_SCHEMA.table_constraints on ");
287
                sql.append("(INFORMATION_SCHEMA.table_constraints.constraint_name = ");
288
                sql.append("INFORMATION_SCHEMA.constraint_column_usage.constraint_name ");
289
                sql.append("and INFORMATION_SCHEMA.table_constraints.table_name = ");
290
                sql.append("INFORMATION_SCHEMA.constraint_column_usage.table_name ");
291
                sql.append("and INFORMATION_SCHEMA.table_constraints.table_schema = ");
292
                sql.append("INFORMATION_SCHEMA.constraint_column_usage.table_schema) ");
293
                sql.append("WHERE INFORMATION_SCHEMA.constraint_column_usage.table_name like '");
294

    
295
                sql.append(params.getTable());
296
                sql.append("' AND INFORMATION_SCHEMA.constraint_column_usage.table_schema like '");
297

    
298
                if (params.getSchema() == null || params.getSchema() == "") {
299
                        sql.append(getDefaultSchema(conn));
300
                } else {
301
                        sql.append(params.getSchema());
302
                }
303

    
304
                if (params.getCatalog() == null || params.getCatalog() == "") {
305
                        if (params.getDBName() != null && params.getDBName() != "") {
306
                                sql.append("' AND INFORMATION_SCHEMA.constraint_column_usage.table_catalog like '");
307
                                sql.append(params.getDBName());
308
                        }
309
                } else {
310
                        sql.append("' AND INFORMATION_SCHEMA.constraint_column_usage.table_catalog like '");
311
                        sql.append(params.getCatalog());
312
                }
313

    
314
                sql.append("' AND constraint_type='PRIMARY KEY'");
315

    
316
                // System.out.println(sql.toString());
317
                try {
318
                        st = conn.createStatement();
319
                        try {
320
                                rs = st.executeQuery(sql.toString());
321
                        } catch (java.sql.SQLException e) {
322
                                throw new JDBCExecuteSQLException(sql.toString(), e);
323
                        }
324
                        while (rs.next()) {
325
                                list.add(rs.getString(1));
326
                        }
327
                        rs.close();
328
                        st.close();
329

    
330
                } catch (java.sql.SQLException e) {
331
                        throw new JDBCSQLException(e);
332
                }
333
                if (list.size() == 0) {
334
                        return null;
335
                }
336

    
337
                return (String[]) list.toArray(new String[0]);
338

    
339
        }
340

    
341

    
342
        private void loadFeatureType(Connection conn,
343
                        EditableFeatureType featureType, String sql, String[] pks,
344
                        String defGeomName, String schema, String table)
345
                        throws DataException {
346

    
347
                Statement stAux = null;
348
                ResultSet rs = null;
349
                try {
350

    
351
                        stAux = conn.createStatement();
352
                        stAux.setFetchSize(1);
353

    
354
                        try {
355
                                rs = stAux.executeQuery(sql);
356
                        } catch (SQLException e) {
357
                                throw new JDBCExecuteSQLException(sql, e);
358
                        }
359
                        ResultSetMetaData rsMetadata = rs.getMetaData();
360

    
361
                        List pksList = null;
362
                        if (pks != null) {
363
                                pksList = Arrays.asList(pks);
364

    
365
                        }
366

    
367
                        int i;
368
                        int geometriesColumns = 0;
369
                        String lastGeometry=null;
370

    
371
                        EditableFeatureAttributeDescriptor attr;
372
                        for (i = 1; i <= rsMetadata.getColumnCount(); i++) {
373
                                attr = getAttributeFromJDBC(featureType, conn, rsMetadata, i);
374
                                if (pksList != null && pksList.contains(attr.getName())) {
375
                                        attr.setIsPrimaryKey(true);
376
                                }
377
                                if (attr.getDataType() == DataTypes.GEOMETRY) {
378
                                        geometriesColumns++;
379
                                        lastGeometry=attr.getName();
380
                                        if (lastGeometry.equals(defGeomName)) {
381
                                                featureType
382
                                                                .setDefaultGeometryAttributeName(defGeomName);
383
                                        }
384

    
385

    
386
                                }
387

    
388

    
389
                        }
390

    
391
                        if (geometriesColumns > 0) {
392
                                loadSRS_and_shapeType(conn, rsMetadata, featureType, schema,
393
                                                table);
394
                        }
395

    
396

    
397
                        if (defGeomName == null && geometriesColumns == 1) {
398
                                featureType.setDefaultGeometryAttributeName(lastGeometry);
399
                                defGeomName = lastGeometry;
400
                        }
401

    
402
                } catch (java.sql.SQLException e) {
403
                        throw new JDBCSQLException(e); // FIXME exception
404
                } finally {
405
                        try{ rs.close(); } catch (Exception e){}
406
                        try{ stAux.close(); } catch (Exception e){}
407

    
408
                }
409

    
410
        }
411

    
412

    
413
        private EditableFeatureAttributeDescriptor getAttributeFromJDBC(
414
                        EditableFeatureType fType, Connection conn,
415
                        ResultSetMetaData rsMetadata, int colIndex) throws JDBCException {
416
                EditableFeatureAttributeDescriptor column;
417
                try {
418

    
419
                        switch (rsMetadata.getColumnType(colIndex)) {
420
                        case java.sql.Types.INTEGER:
421
                                column = fType.add(rsMetadata.getColumnName(colIndex),
422
                                                DataTypes.INT);
423
                                break;
424
                        case java.sql.Types.BIGINT:
425
                                column = fType.add(rsMetadata.getColumnName(colIndex),
426
                                                DataTypes.LONG);
427
                                break;
428
                        case java.sql.Types.REAL:
429
                                column = fType.add(rsMetadata.getColumnName(colIndex),
430
                                                DataTypes.DOUBLE);
431
                                break;
432
                        case java.sql.Types.DOUBLE:
433
                                column = fType.add(rsMetadata.getColumnName(colIndex),
434
                                                DataTypes.DOUBLE);
435
                                break;
436
                        case java.sql.Types.CHAR:
437
                                column = fType.add(rsMetadata.getColumnName(colIndex),
438
                                                DataTypes.STRING);
439
                                break;
440
                        case java.sql.Types.VARCHAR:
441
                                column = fType.add(rsMetadata.getColumnName(colIndex),
442
                                                DataTypes.STRING);
443
                                break;
444
                        case java.sql.Types.FLOAT:
445
                                column = fType.add(rsMetadata.getColumnName(colIndex),
446
                                                DataTypes.FLOAT);
447
                                break;
448
                        case java.sql.Types.DECIMAL:
449
                                column = fType.add(rsMetadata.getColumnName(colIndex),
450
                                                DataTypes.FLOAT);
451
                                break;
452
                        case java.sql.Types.DATE:
453
                                column = fType.add(rsMetadata.getColumnName(colIndex),
454
                                                DataTypes.DATE);
455
                                break;
456
                        case java.sql.Types.TIME:
457
                                column = fType.add(rsMetadata.getColumnName(colIndex),
458
                                                DataTypes.TIME);
459
                                break;
460
                        case java.sql.Types.TIMESTAMP:
461
                                column = fType.add(rsMetadata.getColumnName(colIndex),
462
                                                DataTypes.TIMESTAMP);
463
                                break;
464
                        case java.sql.Types.BOOLEAN:
465
                                column = fType.add(rsMetadata.getColumnName(colIndex),
466
                                                DataTypes.BOOLEAN);
467
                                break;
468
                        case java.sql.Types.OTHER:
469
                                if (rsMetadata.getColumnTypeName(colIndex).equalsIgnoreCase(
470
                                                "geometry")) {
471
                                        column = fType.add(rsMetadata.getColumnName(colIndex),
472
                                                        DataTypes.GEOMETRY);
473
                                        break;
474
                                }
475
                                // No hacemos break para que se quede en default
476

    
477
                        default:
478
                                column = fType.add(rsMetadata.getColumnName(colIndex),
479
                                                DataTypes.OBJECT);
480
                                break;
481
                        }
482
                        // column.setCaseSensitive(rsMetadata.isCaseSensitive(colIndex));
483
                        // column.setSqlType(rsMetadata.getColumnType(colIndex));
484
                        column
485
                                        .setAllowNull(rsMetadata.isNullable(colIndex) == ResultSetMetaData.columnNullable);
486
                        column.setIsAutomatic(rsMetadata.isAutoIncrement(colIndex));
487
                        column.setIsReadOnly(rsMetadata.isReadOnly(colIndex));
488
                        // column.setWritable(rsMetadata.isWritable(colIndex));
489
                        // column.setClassName(rsMetadata.getColumnClassName(colIndex));
490
                        // column.setCatalogName(rsMetadata.getCatalogName(colIndex));
491
                        // column.setDefinitelyWritable(rsMetadata
492
                        // .isDefinitelyWritable(colIndex));
493
                        // column.setLabel(rsMetadata.getColumnLabel(colIndex));
494
                        // column.setSchemaName(rsMetadata.getSchemaName(colIndex));
495
                        // column.setTableName(rsMetadata.getTableName(colIndex));
496
                        // column.setCatalogName(rsMetadata.getCatalogName(colIndex));
497
                        // column.setSqlTypeName();
498
                        // column.setSearchable(rsMetadata.isSearchable(colIndex));
499
                        // column.setSigned(rsMetadata.isSigned(colIndex));
500
                        // column.setCurrency(rsMetadata.isCurrency(colIndex));
501
                        column.setPrecision(rsMetadata.getPrecision(colIndex));
502
                        column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
503

    
504
                } catch (java.sql.SQLException e) {
505
                        throw new JDBCSQLException(e);
506
                }
507

    
508
                return column;
509

    
510
        }
511

    
512
        private String getDefaultSchema(Connection conn)
513
                        throws JDBCException {
514
                if (defaultSchema == null) {
515
                        String sql = "Select current_schema()";
516
                        ResultSet rs = null;
517
                        Statement st = null;
518
                        String schema = null;
519
                        try {
520
                                st = conn.createStatement();
521
                                try {
522
                                        rs = st.executeQuery(sql);
523
                                } catch (java.sql.SQLException e) {
524
                                        throw new JDBCExecuteSQLException(sql, e);
525
                                }
526
                                rs.next();
527
                                schema = rs.getString(1);
528
                        } catch (java.sql.SQLException e) {
529
                                throw new JDBCSQLException(e);
530
                        } finally {
531
                                try {rs.close();} catch (Exception e) {logger.error("Exception clossing resulset", e);};
532
                                try {st.close();} catch (Exception e) {logger.error("Exception clossing statement", e);};
533
                                rs = null;
534
                                st = null;
535
                        }
536
                        defaultSchema = schema;
537
                }
538

    
539
                return defaultSchema;
540
        }
541

    
542
        public Envelope getFullEnvelopeOfField(
543
                        PostgreSQLStoreParameters storeParams,
544
                        String geometryAttrName, Envelope limit)
545
                        throws DataException {
546

    
547
                StringBuilder strb = new StringBuilder();
548
                strb.append("Select asbinary(extent(");
549
                strb.append(geometryAttrName);
550
                strb.append(")) from ");
551

    
552
                if (storeParams.getSQL() != null
553
                                && storeParams.getSQL().trim().length() == 0) {
554
                        strb.append('(');
555
                        strb.append(storeParams.getSQL());
556
                        strb.append(") as __tmp__ ");
557
                } else {
558
                        strb.append(storeParams.tableID());
559
                }
560

    
561

    
562
                if (limit != null){
563
                        strb.append(" where  intersects(GeomFromText('");
564
                        strb.append(limit.toString());
565
                        strb.append("')), boundary(");
566
                        strb.append(geometryAttrName);
567
                        strb.append(")) ");
568
                }
569

    
570
                String sql = strb.toString();
571

    
572

    
573
                ResultSet rs = null;
574
                Statement st = null;
575
                String schema = null;
576
                Connection conn = null;
577

    
578
                GeometryManager geoMan = GeometryLocator.getGeometryManager();
579

    
580
                Envelope fullEnvelope = null;
581
                this.open();
582
                this.begin();
583
                try{
584
                        conn = getConnection();
585
                        st = conn.createStatement();
586
                        try {
587
                                rs = st.executeQuery(sql);
588
                        } catch (java.sql.SQLException e) {
589
                                throw new JDBCExecuteSQLException(sql, e);
590
                        }
591
                        if (!rs.next()) {
592
                                return null;
593
                        }
594

    
595
                        byte[] data = rs.getBytes(1);
596
                        if (data == null) {
597
                                return null;
598
                        }
599
                        initializeFromWKBOperation();
600
                        fromWKBContext.setData(data);
601
                        Geometry geom = (Geometry) fromWKB.invoke(null, fromWKBContext);
602

    
603
                        fullEnvelope = geom.getEnvelope();
604

    
605
                        return fullEnvelope;
606
                } catch (java.sql.SQLException e) {
607
                        throw new JDBCSQLException(e);
608
                } catch (BaseException e) {
609
                        throw new ReadException(user.getName(), e);
610
                } finally {
611
                        try{ rs.close(); } catch (Exception e){};
612
                        try{ st.close(); } catch (Exception e){};
613
                        try{ conn.close(); } catch (Exception e){};
614
                        rs = null;
615
                        st = null;
616
                        conn = null;
617
                        end();
618
                }
619

    
620

    
621
        }
622

    
623
        private void initializeFromWKBOperation() throws BaseException {
624
                if (fromWKB == null) {
625
                        fromWKB = (FromWKB) GeometryLocator.getGeometryManager()
626
                                        .getGeometryOperation(FromWKB.CODE,
627
                                                        Geometry.TYPES.GEOMETRY, Geometry.SUBTYPES.GEOM2D);
628
                        fromWKBContext = new FromWKBGeometryOperationContext();
629

    
630
                }
631
        }
632

    
633
        public Geometry getGeometry(byte[] buffer) throws BaseException {
634
                if (buffer == null) {
635
                        return null;
636
                }
637
                initializeFromWKBOperation();
638
                Geometry geom;
639
                try {
640
                        fromWKBContext.setData(buffer);
641

    
642
                        geom = (Geometry) fromWKB.invoke(null, fromWKBContext);
643
                } finally {
644
                        fromWKBContext.setData(null);
645
                }
646
                return geom;
647
        }
648

    
649
        /**
650
         * Fill <code>featureType</code> geometry attributes with SRS and ShapeType
651
         * information stored in the table GEOMETRY_COLUMNS
652
         *
653
         * @param conn
654
         * @param rsMetadata
655
         * @param featureType
656
         * @throws ReadException
657
         */
658
        private void loadSRS_and_shapeType(Connection conn,
659
                        ResultSetMetaData rsMetadata, EditableFeatureType featureType,
660
                        String baseSchema, String baseTable)
661
                        throws JDBCException {
662

    
663
                Statement st = null;
664
                ResultSet rs = null;
665
                try {
666
                        // Sacamos la lista de los attributos geometricos
667
                        EditableFeatureAttributeDescriptor attr;
668
                        List geoAttrs = new ArrayList();
669

    
670
                        Iterator iter = featureType.iterator();
671
                        while (iter.hasNext()) {
672
                                attr = (EditableFeatureAttributeDescriptor) iter.next();
673
                                if (attr.getDataType() == DataTypes.GEOMETRY) {
674
                                        geoAttrs.add(attr);
675
                                }
676
                        }
677
                        if (geoAttrs.size() < 1) {
678
                                return;
679
                        }
680

    
681

    
682
                        // preparamos un set con las lista de tablas de origen
683
                        // de los campos
684
                        class TableId {
685
                                public String schema=null;
686
                                public String table=null;
687
                                public String field = null;
688

    
689
                                public void appendToSQL(StringBuilder strb) {
690
                                        if (schema == null || schema.length() == 0) {
691
                                                strb
692
                                                                .append("( F_TABLE_SCHEMA = current_schema() AND F_TABLE_NAME = '");
693
                                        } else {
694
                                                strb.append("( F_TABLE_SCHEMA = '");
695
                                                strb.append(schema);
696
                                                strb.append("' AND F_TABLE_NAME = '");
697
                                        }
698
                                        strb.append(table);
699
                                        strb.append("' AND F_GEOMETRY_COLUMN = '");
700
                                        strb.append(field);
701
                                        strb.append("' )");
702
                                }
703

    
704
                        }
705
                        Comparator cmp = new Comparator(){
706
                                public int compare(Object arg0, Object arg1) {
707
                                        TableId a0 = (TableId) arg0;
708
                                        TableId a1 = (TableId) arg1;
709

    
710
                                        if (!a0.field.equals(a1.field)) {
711
                                                return -1;
712
                                        }
713
                                        if (!a0.table.equals(a1.table)) {
714
                                                return -1;
715
                                        }
716
                                        if (!a0.schema.equals(a1.schema)) {
717
                                                return -1;
718
                                        }
719
                                        return 0;
720
                                }
721
                        };
722
                        TreeSet set = new TreeSet(cmp);
723
                        TableId tableId;
724
                        iter = geoAttrs.iterator();
725
                        int rsIndex;
726
                        while (iter.hasNext()) {
727
                                attr = (EditableFeatureAttributeDescriptor) iter.next();
728
                                tableId = new TableId();
729
                                rsIndex = attr.getIndex() + 1;
730

    
731
                                if (baseSchema == null && baseTable == null) {
732
                                        if (rsMetadata instanceof PGResultSetMetaData) {
733
                                                tableId.schema = ((PGResultSetMetaData) rsMetadata)
734
                                                                .getBaseSchemaName(rsIndex);
735
                                                tableId.table = ((PGResultSetMetaData) rsMetadata)
736
                                                                .getBaseTableName(rsIndex);
737
                                                tableId.field = ((PGResultSetMetaData) rsMetadata)
738
                                                                .getBaseColumnName(rsIndex);
739

    
740
                                        } else {
741
                                                tableId.schema = rsMetadata.getSchemaName(rsIndex);
742
                                                tableId.table = rsMetadata.getTableName(rsIndex);
743
                                                tableId.field = rsMetadata.getColumnName(rsIndex);
744
                                        }
745
                                } else {
746
                                        tableId.schema = baseSchema;
747
                                        tableId.table = baseTable;
748
                                        tableId.field = rsMetadata.getColumnName(rsIndex);
749
                                }
750
                                if (tableId.table == null || tableId.table.length() == 0) {
751
                                        // Si no tiene tabla origen (viene de algun calculo por ej.)
752
                                        // lo saltamos ya que no estara en la tabla GEOMETRY_COLUMNS
753
                                        continue;
754
                                }
755
                                set.add(tableId);
756
                        }
757

    
758
                        if (set.size() == 0) {
759
                                return;
760
                        }
761

    
762
                        // Preparamos una sql para que nos saque el resultado
763
                        StringBuilder strb = new StringBuilder();
764
                        strb.append("Select geometry_columns.*,auth_name || ':' || auth_srid as SRSID ");
765
                        strb.append("from geometry_columns left join spatial_ref_sys on ");
766
                        strb.append("geometry_columns.srid = spatial_ref_sys.srid WHERE ");
767
                        iter = set.iterator();
768
                        for (int i=0;i<set.size()-1;i++) {
769
                                tableId = (TableId) iter.next();
770
                                tableId.appendToSQL(strb);
771
                                strb.append(" OR ");
772
                        }
773
                        tableId = (TableId) iter.next();
774
                        tableId.appendToSQL(strb);
775
                        String sql = strb.toString();
776

    
777

    
778
                        st = conn.createStatement();
779
                        try {
780
                                rs = st.executeQuery(sql);
781
                        } catch (SQLException e) {
782
                                throw new JDBCExecuteSQLException(sql, e);
783
                        }
784
                        String srsID;
785
                        int pgSrid;
786
                        int geometryType;
787
                        int geometrySubtype;
788
                        String geomTypeStr;
789
                        int dimensions;
790
                        IProjection srs;
791

    
792
                        while (rs.next()){
793
                                srsID = rs.getString("SRSID");
794
                                pgSrid = rs.getInt("SRID");
795
                                geomTypeStr = rs.getString("TYPE").toUpperCase();
796
                                geometryType = Geometry.TYPES.GEOMETRY;
797
                                if (geomTypeStr.startsWith("POINT")) {
798
                                        geometryType = Geometry.TYPES.POINT;
799
                                } else if (geomTypeStr.startsWith("LINESTRING")) {
800
                                        geometryType = Geometry.TYPES.CURVE;
801
                                } else if (geomTypeStr.startsWith("POLYGON")) {
802
                                        geometryType = Geometry.TYPES.SURFACE;
803
                                } else if (geomTypeStr.startsWith("MULTIPOINT")) {
804
                                        geometryType = Geometry.TYPES.MULTIPOINT;
805
                                } else if (geomTypeStr.startsWith("MULTILINESTRING")) {
806
                                        geometryType = Geometry.TYPES.MULTICURVE;
807
                                } else if (geomTypeStr.startsWith("MULTIPOLYGON")) {
808
                                        geometryType = Geometry.TYPES.MULTISURFACE;
809
                                }
810
                                dimensions = rs.getInt("coord_dimension");
811
                                geometrySubtype = Geometry.SUBTYPES.GEOM2D;
812
                                if (dimensions > 2) {
813
                                        if (dimensions == 3) {
814
                                                if (geomTypeStr.endsWith("M")) {
815
                                                        geometrySubtype = Geometry.SUBTYPES.GEOM2DM;
816
                                                } else {
817
                                                        geometrySubtype = Geometry.SUBTYPES.GEOM3D;
818
                                                }
819

    
820
                                        } else {
821
                                                geometrySubtype = Geometry.SUBTYPES.GEOM3DM;
822
                                        }
823
                                }
824
                                addToPgSRToSRSID(pgSrid, srsID);
825

    
826

    
827
                                iter = geoAttrs.iterator();
828
                                while (iter.hasNext()) {
829
                                        attr = (EditableFeatureAttributeDescriptor) iter.next();
830
                                        rsIndex = attr.getIndex() + 1;
831
                                        if (!rsMetadata.getColumnName(rsIndex).equals(
832
                                                        rs.getString("f_geometry_column"))) {
833
                                                continue;
834
                                        }
835

    
836
                                        if (baseSchema == null && baseTable == null) {
837

    
838
                                                if (rsMetadata instanceof PGResultSetMetaData) {
839
                                                        if (!((PGResultSetMetaData) rsMetadata)
840
                                                                        .getBaseTableName(rsIndex).equals(
841
                                                                                        rs.getString("f_table_name"))) {
842
                                                                continue;
843
                                                        }
844
                                                        String curSchema = rs.getString("f_table_schema");
845
                                                        String metaSchema = ((PGResultSetMetaData) rsMetadata)
846
                                                                        .getBaseSchemaName(rsIndex);
847
                                                        if (!metaSchema.equals(curSchema)) {
848
                                                                if (metaSchema.length() == 0
849
                                                                                && metaSchema == getDefaultSchema(conn)) {
850
                                                                } else {
851
                                                                        continue;
852
                                                                }
853
                                                        }
854

    
855
                                                } else {
856

    
857
                                                        if (!rsMetadata.getTableName(rsIndex).equals(
858
                                                                        rs.getString("f_table_name"))) {
859
                                                                continue;
860
                                                        }
861
                                                        String curSchema = rs.getString("f_table_schema");
862
                                                        String metaSchema = rsMetadata
863
                                                                        .getSchemaName(rsIndex);
864
                                                        if (!metaSchema.equals(curSchema)) {
865
                                                                if (metaSchema.length() == 0
866
                                                                                && metaSchema == getDefaultSchema(conn)) {
867
                                                                } else {
868
                                                                        continue;
869
                                                                }
870
                                                        }
871
                                                }
872
                                        }
873
                                        attr.setGeometryType(geometryType);
874
                                        attr.setGeometrySubType(geometrySubtype);
875
                                        if (srsID != null && srsID.length() > 0) {
876
                                                attr.setSRS(CRSFactory.getCRS(srsID));
877
                                        }
878
                                        iter.remove();
879
                                }
880
                                iter = geoAttrs.iterator();
881
                                while (iter.hasNext()) {
882
                                        attr = (EditableFeatureAttributeDescriptor) iter.next();
883
                                        attr.setSRS(null);
884
                                        attr.setGeometryType(Geometry.TYPES.GEOMETRY);
885

    
886
                                }
887
                        }
888

    
889
                } catch (java.sql.SQLException e) {
890
                        throw new JDBCSQLException(e);
891
                } finally {
892
                        try {rs.close();} catch (Exception e) {        };
893
                        try {st.close();} catch (Exception e) {        };
894
                }
895

    
896
        }
897

    
898
        public String escapeFieldName(String field) {
899
                if (field.matches("[a-z][a-z0-9_]*")) {
900
                        return field;
901
                }
902
                return "\"" + field + "\"";
903

    
904
        }
905

    
906
        public Object dalValueToJDBC(
907
                        FeatureAttributeDescriptor attributeDescriptor, Object object)
908
                                throws WriteException {
909
                if (object == null) {
910
                        return null;
911
                }
912

    
913
                if (attributeDescriptor.getDataType() != DataTypes.GEOMETRY) {
914
                        return object;
915
                }
916
                try {
917
                        Geometry geom = (Geometry) object;
918

    
919
                        toWKBContext.setSrID(-1);
920
                        IProjection srs = attributeDescriptor.getSRS();
921
                        if (srs != null) {
922
                                toWKBContext.setSrID(getPostgisSRID(srs));
923
                        }
924

    
925
                        // TODO optimize this building PGGeometry by code
926
                        byte[] wkb = (byte[]) geom
927
                                        .invokeOperation(ToWKB.CODE, toWKBContext);
928
                        if (wkb == null) {
929
                                // FIXME excpetion
930
                                throw new IllegalArgumentException();
931
                        }
932

    
933
                        return wkb;
934
                } catch (Exception e) {
935
                        throw new WriteException(this.name, e);
936
                }
937
        }
938

    
939
        /**
940
         * Contains an action to execute with
941
         * {@link PostgreSQLHelper#doConnectionAction(ConnectionAction)}
942
         *
943
         * @see {@link PostgreSQLHelper#doConnectionAction(ConnectionAction)},
944
         *      {@link TransactionalAction}
945
         */
946
        public interface ConnectionAction {
947
                Object action(Connection conn) throws DataException;
948
        }
949

    
950
        /**
951
         * Contains an action to execute with
952
         * {@link PostgreSQLHelper#doConnectionAction(ConnectionAction)} inside of a
953
         * DB transaction.
954
         *
955
         * @see {@link PostgreSQLHelper#doConnectionAction(ConnectionAction)},
956
         *      {@link ConnectionAction}
957
         */
958
        public interface TransactionalAction extends ConnectionAction {
959

    
960
                /**
961
                 * If before run <code>action</code> there's a transaction open and this
962
                 * methos returns <code>false</code> an exception will be throwed
963
                 *
964
                 * @return
965
                 */
966
                boolean continueTransactionAllowed();
967

    
968
        }
969

    
970
        /**
971
         * Executes an atomic action that uses an DB Connection.<br>
972
         *
973
         * This methos prepares a connection and close it at the end of execution of
974
         * action.<br>
975
         *
976
         * if <code>action</code> is an instance of {@link TransactionalAction} the
977
         * action will be execute inside of a DB transaction.
978
         *
979
         *
980
         * @param action
981
         * @throws Exception
982
         */
983
        public Object doConnectionAction(ConnectionAction action)
984
                        throws Exception {
985
                Object result = null;
986
                Connection conn = null;
987
                boolean beginTrans = false;
988
                this.open();
989
                this.begin();
990
                try {
991

    
992

    
993
                        conn = this.getConnection();
994
                        if (action instanceof TransactionalAction){
995
                                // XXX OJO esta condicion NO ES FIABLE
996
                                if (!conn.getAutoCommit()) {
997
                                        if (!((TransactionalAction) action)
998
                                                        .continueTransactionAllowed()) {
999
                                                // FIXME exception
1000
                                                throw new Exception();
1001
                                        }
1002
                                }
1003
                                try {
1004
                                        conn.setAutoCommit(false);
1005
                                } catch (SQLException e) {
1006
                                        throw new JDBCSQLException(e);
1007
                                }
1008
                                beginTrans = true;
1009
                        }
1010

    
1011
                        result = action.action(conn);
1012

    
1013
                        if (beginTrans) {
1014
                                try {
1015
                                        conn.commit();
1016
                                } catch (SQLException e) {
1017
                                        throw new JDBCTransactionCommitException(e);
1018
                                }
1019
                        }
1020

    
1021
                        return result;
1022

    
1023

    
1024
                } catch (Exception e) {
1025

    
1026
                        if (beginTrans) {
1027
                                try {
1028
                                        conn.rollback();
1029
                                } catch (Exception e1) {
1030
                                        throw new JDBCTransactionRollbackException(e1, e);
1031
                                }
1032
                        }
1033
                        throw e;
1034

    
1035
                } finally {
1036
                        try {
1037
                                conn.close();
1038
                        } catch (Exception e1) {
1039
                                logger.error("Exception on close connection", e1);
1040
                        }
1041
                        this.end();
1042
                }
1043

    
1044
        }
1045

    
1046
        public String getSqlColumnTypeDescription(FeatureAttributeDescriptor attr) {
1047
                switch (attr.getDataType()) {
1048
                case DataTypes.STRING:
1049
                        if (attr.getSize() < 1 || attr.getSize() > 255) {
1050
                                return "text";
1051
                        } else {
1052
                                return "varchar(" + attr.getSize() + ")";
1053
                        }
1054
                case DataTypes.BOOLEAN:
1055
                        return "bool";
1056

    
1057
                case DataTypes.BYTE:
1058
                        return "smallint";
1059

    
1060
                case DataTypes.DATE:
1061
                        return "date";
1062

    
1063
                case DataTypes.TIMESTAMP:
1064
                        return "timestamp";
1065

    
1066
                case DataTypes.TIME:
1067
                        return "time";
1068

    
1069
                case DataTypes.DOUBLE:
1070
                        if (attr.getPrecision() > 0) {
1071
                                return "double precision" + attr.getPrecision();
1072
                        } else {
1073
                                return "double precision";
1074
                        }
1075
                case DataTypes.FLOAT:
1076
                        return "real";
1077

    
1078
                case DataTypes.GEOMETRY:
1079
                        return "geometry";
1080

    
1081
                case DataTypes.INT:
1082
                        if (attr.isAutomatic()) {
1083
                                return "serial";
1084
                        } else {
1085
                                return "integer";
1086
                        }
1087
                case DataTypes.LONG:
1088
                        if (attr.isAutomatic()) {
1089
                                return "bigserial";
1090
                        } else {
1091
                                return "bigint";
1092
                        }
1093

    
1094
                default:
1095
                        throw new UnsupportedDataTypeException(attr.getDataTypeName(), attr
1096
                                        .getDataType());
1097
                }
1098
        }
1099

    
1100
        public void addSqlFiledDescription(FeatureAttributeDescriptor attr,
1101
                        StringBuilder strb) throws DataException {
1102

    
1103
                /**
1104
                 * column_name data_type [ DEFAULT default_expr ] [ column_constraint [
1105
                 * ... ] ]
1106
                 *
1107
                 * where column_constraint is:
1108
                 *
1109
                 * [ CONSTRAINT constraint_name ] { NOT NULL | NULL | UNIQUE | PRIMARY
1110
                 * KEY | CHECK (expression) | REFERENCES reftable [ ( refcolumn ) ] [
1111
                 * MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON
1112
                 * UPDATE action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY
1113
                 * DEFERRED | INITIALLY IMMEDIATE ]
1114
                 */
1115

    
1116
                // name
1117
                strb.append(attr.getName());
1118
                strb.append(" ");
1119

    
1120

    
1121
                // Type
1122
                strb.append(this.getSqlColumnTypeDescription(attr));
1123
                strb.append(" ");
1124

    
1125
                // Default
1126
                if (attr.getDefaultValue() == null) {
1127
                        if (attr.allowNull()) {
1128
                                strb.append("DEFAULT NULL ");
1129
                        }
1130
                } else {
1131
                        String value = dalValueToJDBC(attr, attr.getDefaultValue())
1132
                        .toString();
1133
                        strb.append("DEFAULT '");
1134
                        strb.append(value);
1135
                        strb.append("' ");
1136
                }
1137

    
1138
                // Null
1139
                if (attr.allowNull()) {
1140
                        strb.append("NOT NULL ");
1141
                } else {
1142
                        strb.append("NULL ");
1143
                }
1144

    
1145
                // Primery key
1146
                if (attr.isPrimaryKey()) {
1147
                        strb.append("PRIMARY KEY ");
1148
                }
1149
        }
1150

    
1151
        public int getPostgisGeomDimensions(int geometrySubType) {
1152
                switch (geometrySubType) {
1153
                case Geometry.SUBTYPES.GEOM2D:
1154
                        return 2;
1155
                case Geometry.SUBTYPES.GEOM2DM:
1156
                case Geometry.SUBTYPES.GEOM3D:
1157
                        return 3;
1158

    
1159
                case Geometry.SUBTYPES.GEOM3DM:
1160
                        return 4;
1161
                default:
1162
                        throw new UnsupportedDataTypeException(
1163
                                        DataTypes.TYPE_NAMES[DataTypes.GEOMETRY],
1164
                                        DataTypes.GEOMETRY);
1165
                }
1166
        }
1167

    
1168
        public String getPostgisGeomType(int geometryType, int geometrySubType) {
1169
                String pgGeomType;
1170
                switch (geometryType) {
1171
                case Geometry.TYPES.GEOMETRY:
1172
                        pgGeomType = "GEOMETRY";
1173
                        break;
1174
                case Geometry.TYPES.POINT:
1175
                        pgGeomType = "POINT";
1176
                        break;
1177
                case Geometry.TYPES.CURVE:
1178
                        pgGeomType = "LINESTRING";
1179
                        break;
1180
                case Geometry.TYPES.SURFACE:
1181
                        pgGeomType = "POLYGON";
1182
                        break;
1183
                case Geometry.TYPES.MULTIPOINT:
1184
                        pgGeomType = "MULTIPOINT";
1185
                        break;
1186
                case Geometry.TYPES.MULTICURVE:
1187
                        pgGeomType = "MULTILINESTRING";
1188
                        break;
1189
                case Geometry.TYPES.MULTISURFACE:
1190
                        pgGeomType = "MULTIPOLYGON";
1191
                        break;
1192
                default:
1193
                        throw new UnsupportedGeometryException(geometryType,
1194
                                        geometrySubType);
1195
                }
1196
                if (geometrySubType == Geometry.SUBTYPES.GEOM2DM
1197
                                || geometrySubType == Geometry.SUBTYPES.GEOM3DM) {
1198
                        pgGeomType = pgGeomType + "M";
1199
                } else if (geometrySubType == Geometry.SUBTYPES.GEOM2DZ) {
1200
                        throw new UnsupportedGeometryException(geometryType,
1201
                                        geometrySubType);
1202
                }
1203
                return pgGeomType;
1204
        }
1205

    
1206
        public int getPostgisSRID(String srs) {
1207
                if (srs != null) {
1208
                        Integer pgSRID = (Integer) srsID2pgSR.get(srs);
1209
                        if (pgSRID != null) {
1210
                                return pgSRID.intValue();
1211
                        }
1212

    
1213
                        return searchpgSRID(srs);
1214

    
1215
                }
1216
                return -1;
1217
        }
1218

    
1219

    
1220
        public int getPostgisSRID(IProjection srs) {
1221
                if (srs != null) {
1222
                        Integer pgSRID = (Integer) srsID2pgSR.get(srs.getAbrev());
1223
                        if (pgSRID != null) {
1224
                                return pgSRID.intValue();
1225
                        }
1226

    
1227
                        return searchpgSRID(srs);
1228

    
1229
                }
1230
                return -1;
1231
        }
1232

    
1233
        private int searchpgSRID(final IProjection srs) {
1234
                if (srs == null) {
1235
                        return -1;
1236
                }
1237
                return searchpgSRID(srs.getAbrev());
1238
        }
1239

    
1240
        private int searchpgSRID(final String srsID) {
1241
                if (srsID == null) {
1242
                        return -1;
1243
                }
1244

    
1245
                ConnectionAction action = new ConnectionAction(){
1246

    
1247
                        public Object action(Connection conn) throws DataException {
1248
                                // select srid from spatial_ref_sys where auth_name = 'EPSG' and
1249
                                // auth_srid = 23030
1250
                                String[] abrev = srsID.split(":");
1251
                                StringBuilder sqlb = new StringBuilder();
1252
                                sqlb.append("select srid from spatial_ref_sys where ");
1253
                                if (abrev.length > 1) {
1254
                                        sqlb.append("auth_name = ? and ");
1255
                                }
1256
                                sqlb.append("auth_srid = ?");
1257

    
1258
                                String sql = sqlb.toString();
1259
                                PreparedStatement st;
1260
                                try {
1261
                                        st = conn.prepareStatement(sql);
1262
                                } catch (SQLException e){
1263
                                        throw new JDBCPreparingSQLException(sql,e);
1264
                                }
1265
                                ResultSet rs = null;
1266
                                try{
1267
                                        int i=0;
1268
                                        if (abrev.length > 1){
1269
                                                st.setString(i+1, abrev[i]);
1270
                                                i++;
1271
                                        }
1272
                                        st.setInt(i + 1, Integer.parseInt(abrev[i]));
1273

    
1274
                                        try{
1275
                                                rs = st.executeQuery();
1276
                                        } catch (SQLException e){
1277
                                                throw new JDBCExecutePreparedSQLException(sql, abrev, e);
1278
                                        }
1279

    
1280
                                        if (!rs.next()) {
1281
                                                return null;
1282
                                        }
1283

    
1284
                                        return new Integer(rs.getInt(1));
1285

    
1286
                                } catch (SQLException e){
1287
                                        throw new JDBCSQLException(e);
1288
                                } finally{
1289
                                        try {rs.close(); } catch (Exception e) {};
1290
                                        try {st.close(); } catch (Exception e) {};
1291
                                }
1292

    
1293
                        }
1294

    
1295
                };
1296

    
1297
                Integer pgSRSID = null;
1298
                try {
1299
                        pgSRSID = (Integer) doConnectionAction(action);
1300
                } catch (Exception e) {
1301
                        logger.error("Excetion searching pgSRS", e);
1302
                        return -1;
1303
                }
1304

    
1305
                if (pgSRSID != null) {
1306
                        addToPgSRToSRSID(pgSRSID.intValue(), srsID);
1307
                        return pgSRSID.intValue();
1308
                }
1309
                return -1;
1310

    
1311
        }
1312

    
1313
        private void addToPgSRToSRSID(int pgSRID, String srsId) {
1314
                if (pgSRID < 0 || srsId == null || srsId.length() == 0) {
1315
                        return;
1316
                }
1317
                Integer pgSRIDInteger = new Integer(pgSRID);
1318
                pgSR2SRSID.put(pgSRIDInteger, srsId);
1319
                srsID2pgSR.put(srsId, pgSRIDInteger);
1320
        }
1321

    
1322
        public boolean isOpen() {
1323
                return isOpen;
1324
        }
1325

    
1326
        public String[] getSqlGeometyFieldAdd(FeatureAttributeDescriptor attr,
1327
                        String table, String schema) {
1328
                // SELECT AddGeometryColumn({schema}, {table}, {field}, {srid}(int),
1329
                // {geomType}(Str), {dimensions}(int))
1330

    
1331
                // gemoType:
1332
                /*
1333
                 * POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING,
1334
                 * MULTIPOLYGON, GEOMETRYCOLLECTION POINTM, LINESTRINGM, POLYGONM,
1335
                 * MULTIPOINTM, MULTILINESTRINGM, MULTIPOLYGONM, GEOMETRYCOLLECTIONM
1336
                 */
1337

    
1338
                List sqls = new ArrayList();
1339

    
1340
                StringBuilder strb = new StringBuilder();
1341
                strb.append("SELECT AddGeometryColumn('");
1342
                if (schema != null && schema.length() > 0) {
1343
                        strb.append(schema);
1344
                        strb.append("', '");
1345
                }
1346
                strb.append(table);
1347
                strb.append("', '");
1348
                strb.append(attr.getName());
1349
                strb.append("', ");
1350
                // strb.append("-1");
1351
                 strb.append(getPostgisSRID(attr.getSRS()));
1352
                strb.append(", '");
1353
                strb.append(getPostgisGeomType(attr.getGeometryType(), attr
1354
                                .getGeometrySubType()));
1355
                strb.append("', ");
1356
                strb.append(getPostgisGeomDimensions(attr.getGeometrySubType()));
1357
                strb.append(")");
1358

    
1359

    
1360
                sqls.add(strb.toString());
1361

    
1362
                /*ALTER TABLE muni10000_peq_test DROP CONSTRAINT enforce_srid_the_geom;*/
1363
                /*
1364
                strb = new StringBuilder();
1365
                strb.append("Alter table ");
1366
                if (schema != null && schema.length() > 0) {
1367
                        strb.append(schema);
1368
                        strb.append(".");
1369
                }
1370
                strb.append("f_table_name = '");
1371
                strb.append(table);
1372
                strb.append("' AND f_geometry_column = '");
1373
                strb.append(attr.getName());
1374
                strb.append("' AND srid = -1");
1375

1376

1377
                sqls.add(strb.toString());
1378
                */
1379
                return (String[]) sqls.toArray(new String[sqls.size()]);
1380
        }
1381

    
1382
        public String getSqlFieldName(FeatureAttributeDescriptor attribute) {
1383
                if (attribute.getDataType() == DataTypes.GEOMETRY) {
1384
                        return "asBinary(" + escapeFieldName(attribute.getName()) + ")";
1385
                }
1386
                return escapeFieldName(attribute.getName());
1387
        }
1388

    
1389
        public FeatureAttributeDescriptor[] getPkFromFType(FeatureType fType) {
1390
                List pk = new ArrayList();
1391
                Iterator iter = fType.iterator();
1392
                FeatureAttributeDescriptor attr;
1393
                while (iter.hasNext()) {
1394
                        attr = (FeatureAttributeDescriptor) iter.next();
1395
                        if (attr.isPrimaryKey()) {
1396
                                pk.add(attr);
1397
                        }
1398
                }
1399
                return (FeatureAttributeDescriptor[]) pk
1400
                                .toArray(new FeatureAttributeDescriptor[0]);
1401
        }
1402
}