Revision 161

View differences:

tags/org.gvsig.postgresql-2.0.37/org.gvsig.postgresql.provider/src/main/java/org/gvsig/fmap/dal/store/postgresql/PostgreSQLHelper.java
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.Properties;
45
import java.util.TreeMap;
46
import java.util.TreeSet;
47

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

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

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

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

  
93
	private Map pgSR2SRSID = new TreeMap();
94
	private Map srsID2pgSR = new TreeMap();
95
	
96
	private static Properties beforePostgis13 = null;
97
    private int[] postGISVersion = { 0,0,0 };
98
    private boolean versionSet = false;
99

  
100
	PostgreSQLHelper(JDBCHelperUser consumer,
101
			PostgreSQLConnectionParameters params)
102
			throws InitializeException {
103

  
104
		super(consumer, params);
105
	}
106

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

  
121

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

  
149
		return defaultSchema;
150
	}
151

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

  
157
        StringBuilder strb = new StringBuilder();
158
        strb.append("Select " + getFunctionName("ST_AsBinary") + "("
159
                + getFunctionName("ST_Extent") + "(");
160
        strb.append(escapeFieldName(geometryAttrName));
161
        strb.append(")) from ");
162

  
163
        if (storeParams.getSQL() != null
164
                && storeParams.getSQL().trim().length() > 0) {
165
            strb.append('(');
166
            strb.append(storeParams.getSQL());
167
            strb.append(") as _subquery_alias_ ");
168
        } else {
169
            strb.append(storeParams.tableID());
170
        }
171

  
172
        if (limit != null || (storeParams.getBaseFilter() != null
173
                && storeParams.getBaseFilter().trim().length() > 0)) {
174
            strb.append(" where  ");
175

  
176
            if (limit != null) {
177
                strb.append(" ( " + getFunctionName("ST_Intersects") + "("
178
                        + getFunctionName("ST_GeomFromText") + "('");
179
                String workAreaWkt = null;
180
                try {
181
                    workAreaWkt = limit.getGeometry().convertToWKT();
182
                } catch (Exception e) {
183
                    throw new CreateGeometryException(e);
184
                }
185
                strb.append(workAreaWkt);
186
                strb.append("', ");
187

  
188
                IProjection proj = storeParams.getCRS();
189
                int sridInt = this.getProviderSRID(proj);
190
                if (sridInt == -1) {
191
                    throw new CreateGeometryException(
192
                            new Exception("CRS is null or unknown."));
193
                } else {
194
                    strb.append(Integer.toString(sridInt));
195
                }
196
                strb.append("), " + getFunctionName("ST_Envelope") + "(");
197
                strb.append(escapeFieldName(geometryAttrName));
198
                strb.append(")) ) ");
199

  
200
            }
201
            if (storeParams.getBaseFilter() != null && storeParams.getBaseFilter().trim().length() > 0) {
202
                if (limit != null) {
203
                    strb.append(" and ");
204
                }
205
                strb.append(" ( ");
206
                strb.append(storeParams.getBaseFilter());
207
                strb.append(" ) ");
208
            }
209

  
210
        }
211

  
212
        final String sql = strb.toString();
213

  
214
        this.open();
215

  
216
        return (Envelope) getResource().execute(new ResourceAction() {
217
            public String toString() {
218
                return "getEnvelope";
219
            }
220

  
221
            public Object run() throws Exception {
222
                ResultSet rs = null;
223
                Statement st = null;
224
                Connection conn = null;
225
                Envelope fullEnvelope = null;
226

  
227
                Envelope emptyEnv
228
                        = geomManager.createEnvelope(Geometry.SUBTYPES.GEOM2D);
229

  
230
                try {
231

  
232
                    conn = getConnection();
233
                    st = conn.createStatement();
234
                    try {
235
                        rs = JDBCHelper.executeQuery(st, sql);
236
                    } catch (java.sql.SQLException e) {
237
                        throw new JDBCExecuteSQLException(sql, e);
238
                    }
239
                    if (!rs.next()) {
240
                        return emptyEnv;
241
                    }
242

  
243
                    byte[] data = rs.getBytes(1);
244
                    if (data == null) {
245
                        return emptyEnv;
246
                    }
247

  
248
                    Geometry geom = geomManager.createFrom(data);
249

  
250
                    fullEnvelope = geom.getEnvelope();
251

  
252
                    return fullEnvelope;
253
                } catch (java.sql.SQLException e) {
254
                    throw new JDBCSQLException(e);
255
                } catch (BaseException e) {
256
                    throw new ReadException(user.getProviderName(), e);
257
                } finally {
258
                    try {
259
                        rs.close();
260
                    } catch (Exception e) {
261
                    }
262
                    try {
263
                        st.close();
264
                    } catch (Exception e) {
265
                    }
266
                    try {
267
                        conn.close();
268
                    } catch (Exception e) {
269
                    }
270
                    rs = null;
271
                    st = null;
272
                    conn = null;
273
                }
274
            }
275
        });
276
    }
277

  
278
	@Override
279
	protected boolean supportsGeometry() {
280
		return true;
281
	}
282

  
283
	/**
284
	 * Fill <code>featureType</code> geometry attributes with SRS and ShapeType
285
	 * information stored in the table GEOMETRY_COLUMNS
286
	 *
287
	 * @param conn
288
	 * @param rsMetadata
289
	 * @param featureType
290
	 * @throws ReadException
291
	 */
292
	protected void loadSRS_and_shapeType(Connection conn,
293
			ResultSetMetaData rsMetadata, EditableFeatureType featureType,
294
			String baseSchema, String baseTable)
295
			throws JDBCException {
296

  
297
		Statement st = null;
298
		ResultSet rs = null;
299
		try {
300
			// Sacamos la lista de los attributos geometricos
301
			EditableFeatureAttributeDescriptor attr;
302
			List geoAttrs = new ArrayList();
303

  
304
			Iterator iter = featureType.iterator();
305
			while (iter.hasNext()) {
306
				attr = (EditableFeatureAttributeDescriptor) iter.next();
307
				if (attr.getType() == DataTypes.GEOMETRY) {
308
					geoAttrs.add(attr);
309
				}
310
			}
311
			if (geoAttrs.size() < 1) {
312
				return;
313
			}
314

  
315

  
316
			// preparamos un set con las lista de tablas de origen
317
			// de los campos
318
			class TableId {
319
				public String schema=null;
320
				public String table=null;
321
				public String field = null;
322

  
323
				public void appendToSQL(StringBuilder strb) {
324
					if (schema == null || schema.length() == 0) {
325
						strb
326
								.append("( F_TABLE_SCHEMA = current_schema() AND F_TABLE_NAME = '");
327
					} else {
328
						strb.append("( F_TABLE_SCHEMA = '");
329
						strb.append(schema);
330
						strb.append("' AND F_TABLE_NAME = '");
331
					}
332
					strb.append(table);
333
					strb.append("' AND F_GEOMETRY_COLUMN = '");
334
					strb.append(field);
335
					strb.append("' )");
336
				}
337

  
338
			}
339
			Comparator cmp = new Comparator(){
340
				public int compare(Object arg0, Object arg1) {
341
					TableId a0 = (TableId) arg0;
342
					TableId a1 = (TableId) arg1;
343

  
344
					int aux = a0.field.compareTo(a1.field);
345
					if (aux != 0) {
346
					    return aux;
347
					}
348

  
349
					aux = a0.table.compareTo(a1.table);
350
                    if (aux != 0) {
351
                        return aux;
352
                    }
353
					
354
                    if (a0.schema == null) {
355
                        if (a1.schema == null) {
356
                            aux = 0;
357
                        } else {
358
                            aux = -1;
359
                        }
360
                    } else {
361
                        if (a1.schema == null) {
362
                            aux = -1;
363
                        } else {
364
                            aux = a0.schema.compareTo(a1.schema);
365
                        }
366
                    }
367
					return aux;
368
				}
369
			};
370
			TreeSet set = new TreeSet(cmp);
371
			TableId tableId;
372
			iter = geoAttrs.iterator();
373
			int rsIndex;
374
			while (iter.hasNext()) {
375
				attr = (EditableFeatureAttributeDescriptor) iter.next();
376
				tableId = new TableId();
377
				rsIndex = attr.getIndex() + 1;
378

  
379
				if (baseSchema == null && baseTable == null) {
380
					if (rsMetadata instanceof PGResultSetMetaData) {
381
						tableId.schema = ((PGResultSetMetaData) rsMetadata)
382
								.getBaseSchemaName(rsIndex);
383
						tableId.table = ((PGResultSetMetaData) rsMetadata)
384
								.getBaseTableName(rsIndex);
385
						tableId.field = ((PGResultSetMetaData) rsMetadata)
386
								.getBaseColumnName(rsIndex);
387

  
388
					} else {
389
						tableId.schema = rsMetadata.getSchemaName(rsIndex);
390
						tableId.table = rsMetadata.getTableName(rsIndex);
391
						tableId.field = rsMetadata.getColumnName(rsIndex);
392
					}
393
				} else {
394
					tableId.schema = baseSchema;
395
					tableId.table = baseTable;
396
					tableId.field = rsMetadata.getColumnName(rsIndex);
397
				}
398
				if (tableId.table == null || tableId.table.length() == 0) {
399
					// Si no tiene tabla origen (viene de algun calculo por ej.)
400
					// lo saltamos ya que no estara en la tabla GEOMETRY_COLUMNS
401
					continue;
402
				}
403
				set.add(tableId);
404
			}
405

  
406
			if (set.size() == 0) {
407
				return;
408
			}
409

  
410
			// Preparamos una sql para que nos saque el resultado
411
			StringBuilder strb = new StringBuilder();
412
			strb.append("Select geometry_columns.*,auth_name || ':' || auth_srid as SRSID ");
413
			strb.append("from geometry_columns left join spatial_ref_sys on ");
414
			strb.append("geometry_columns.srid = spatial_ref_sys.srid WHERE ");
415
			iter = set.iterator();
416
			for (int i=0;i<set.size()-1;i++) {
417
				tableId = (TableId) iter.next();
418
				tableId.appendToSQL(strb);
419
				strb.append(" OR ");
420
			}
421
			tableId = (TableId) iter.next();
422
			tableId.appendToSQL(strb);
423
			String sql = strb.toString();
424

  
425

  
426
			st = conn.createStatement();
427
			try {
428
				rs = JDBCHelper.executeQuery(st,sql);
429
			} catch (SQLException e) {
430
				throw new JDBCExecuteSQLException(sql, e);
431
			}
432
			String srsID;
433
			int pgSrid;
434
			int geometryType;
435
			int geometrySubtype;
436
			String geomTypeStr;
437
			int dimensions;
438
			IProjection srs;
439

  
440
			while (rs.next()){
441
				srsID = rs.getString("SRSID");
442
				pgSrid = rs.getInt("SRID");
443
				geomTypeStr = rs.getString("TYPE").toUpperCase();
444
				geometryType = Geometry.TYPES.GEOMETRY;
445
				if (geomTypeStr.startsWith("POINT")) {
446
					geometryType = Geometry.TYPES.POINT;
447
				} else if (geomTypeStr.startsWith("LINESTRING")) {
448
					geometryType = Geometry.TYPES.CURVE;
449
				} else if (geomTypeStr.startsWith("POLYGON")) {
450
					geometryType = Geometry.TYPES.SURFACE;
451
				} else if (geomTypeStr.startsWith("MULTIPOINT")) {
452
					geometryType = Geometry.TYPES.MULTIPOINT;
453
				} else if (geomTypeStr.startsWith("MULTILINESTRING")) {
454
					geometryType = Geometry.TYPES.MULTICURVE;
455
				} else if (geomTypeStr.startsWith("MULTIPOLYGON")) {
456
					geometryType = Geometry.TYPES.MULTISURFACE;
457
				}
458
				dimensions = rs.getInt("coord_dimension");
459
				geometrySubtype = Geometry.SUBTYPES.GEOM2D;
460
				if (dimensions > 2) {
461
					if (dimensions == 3) {
462
						if (geomTypeStr.endsWith("M")) {
463
							geometrySubtype = Geometry.SUBTYPES.GEOM2DM;
464
						} else {
465
							geometrySubtype = Geometry.SUBTYPES.GEOM3D;
466
						}
467

  
468
					} else {
469
						geometrySubtype = Geometry.SUBTYPES.GEOM3DM;
470
					}
471
				}
472
				addToPgSRToSRSID(pgSrid, srsID);
473

  
474

  
475
				iter = geoAttrs.iterator();
476
				while (iter.hasNext()) {
477
					attr = (EditableFeatureAttributeDescriptor) iter.next();
478
					rsIndex = attr.getIndex() + 1;
479
					if (!rsMetadata.getColumnName(rsIndex).equals(
480
							rs.getString("f_geometry_column"))) {
481
						continue;
482
					}
483

  
484
					if (baseSchema == null && baseTable == null) {
485

  
486
						if (rsMetadata instanceof PGResultSetMetaData) {
487
							if (!((PGResultSetMetaData) rsMetadata)
488
									.getBaseTableName(rsIndex).equals(
489
											rs.getString("f_table_name"))) {
490
								continue;
491
							}
492
							String curSchema = rs.getString("f_table_schema");
493
							String metaSchema = ((PGResultSetMetaData) rsMetadata)
494
									.getBaseSchemaName(rsIndex);
495
							if (!metaSchema.equals(curSchema)) {
496
								if (metaSchema.length() == 0
497
										&& metaSchema == getDefaultSchema(conn)) {
498
								} else {
499
									continue;
500
								}
501
							}
502

  
503
						} else {
504

  
505
							if (!rsMetadata.getTableName(rsIndex).equals(
506
									rs.getString("f_table_name"))) {
507
								continue;
508
							}
509
							String curSchema = rs.getString("f_table_schema");
510
							String metaSchema = rsMetadata
511
									.getSchemaName(rsIndex);
512
							if (!metaSchema.equals(curSchema)) {
513
								if (metaSchema.length() == 0
514
										&& metaSchema == getDefaultSchema(conn)) {
515
								} else {
516
									continue;
517
								}
518
							}
519
						}
520
					}
521
					attr.setGeometryType(geometryType);
522
					attr.setGeometrySubType(geometrySubtype);
523
					if (srsID != null && srsID.length() > 0) {
524
						attr.setSRS(CRSFactory.getCRS(srsID));
525
					}
526
					iter.remove();
527
				}
528
				iter = geoAttrs.iterator();
529
				while (iter.hasNext()) {
530
					attr = (EditableFeatureAttributeDescriptor) iter.next();
531
					attr.setSRS(null);
532
					attr.setGeometryType(Geometry.TYPES.GEOMETRY);
533

  
534
				}
535
			}
536

  
537
		} catch (java.sql.SQLException e) {
538
			throw new JDBCSQLException(e);
539
		} finally {
540
			try {rs.close();} catch (Exception e) {	};
541
			try {st.close();} catch (Exception e) {	};
542
		}
543

  
544
	}
545

  
546

  
547
	public String getSqlColumnTypeDescription(FeatureAttributeDescriptor attr) {
548
		if (attr.getType() == DataTypes.GEOMETRY) {
549
			return "geometry";
550
		}
551
		return super.getSqlColumnTypeDescription(attr);
552
	}
553

  
554

  
555
	public int getPostgisGeomDimensions(int geometrySubType) {
556
		switch (geometrySubType) {
557
		case Geometry.SUBTYPES.GEOM2D:
558
			return 2;
559
		case Geometry.SUBTYPES.GEOM2DM:
560
		case Geometry.SUBTYPES.GEOM3D:
561
			return 3;
562

  
563
		case Geometry.SUBTYPES.GEOM3DM:
564
			return 4;
565
		default:
566
			throw new UnsupportedDataTypeException(
567
					ToolsLocator.getDataTypesManager().getTypeName(DataTypes.GEOMETRY),
568
					DataTypes.GEOMETRY);
569
		}
570
	}
571

  
572
	public String getPostgisGeomType(int geometryType, int geometrySubType) {
573
		String pgGeomType;
574
		switch (geometryType) {
575
		case Geometry.TYPES.GEOMETRY:
576
			pgGeomType = "GEOMETRY";
577
			break;
578
		case Geometry.TYPES.POINT:
579
			pgGeomType = "POINT";
580
			break;
581
		case Geometry.TYPES.CURVE:
582
			pgGeomType = "LINESTRING";
583
			break;
584
		case Geometry.TYPES.SURFACE:
585
			pgGeomType = "POLYGON";
586
			break;
587
		case Geometry.TYPES.MULTIPOINT:
588
			pgGeomType = "MULTIPOINT";
589
			break;
590
		case Geometry.TYPES.MULTICURVE:
591
			pgGeomType = "MULTILINESTRING";
592
			break;
593
		case Geometry.TYPES.MULTISURFACE:
594
			pgGeomType = "MULTIPOLYGON";
595
			break;
596
		default:
597
                    logger.warn("Can't determine PostGIS geometry type, use GEOMETRY.");
598
                    pgGeomType = "GEOMETRY";
599
		}
600
		if (geometrySubType == Geometry.SUBTYPES.GEOM2DM
601
				|| geometrySubType == Geometry.SUBTYPES.GEOM3DM) {
602
			pgGeomType = pgGeomType + "M";
603
		} /* else  if (geometrySubType == Geometry.SUBTYPES.GEOM3D) {
604
			throw new UnsupportedGeometryException(geometryType,
605
					geometrySubType);
606
                   /
607
		} */
608
		return pgGeomType;
609
	}
610

  
611
	public int getProviderSRID(String srs) {
612
		if (srs != null) {
613
			Integer pgSRID = (Integer) srsID2pgSR.get(srs);
614
			if (pgSRID != null) {
615
				return pgSRID.intValue();
616
			}
617

  
618
			return searchpgSRID(srs);
619

  
620
		}
621
		return -1;
622
	}
623

  
624

  
625
	public int getProviderSRID(IProjection srs) {
626
		if (srs != null) {
627
			Integer pgSRID = (Integer) srsID2pgSR.get(srs.getAbrev());
628
			if (pgSRID != null) {
629
				return pgSRID.intValue();
630
			}
631

  
632
			return searchpgSRID(srs);
633

  
634
		}
635
		return -1;
636
	}
637

  
638
	private int searchpgSRID(final IProjection srs) {
639
		if (srs == null) {
640
			return -1;
641
		}
642
		return searchpgSRID(srs.getAbrev());
643
	}
644

  
645
	private int searchpgSRID(final String srsID) {
646
		if (srsID == null) {
647
			return -1;
648
		}
649

  
650
		ConnectionAction action = new ConnectionAction(){
651

  
652
			public Object action(Connection conn) throws DataException {
653

  
654
				String[] abrev = srsID.split(":");
655
				StringBuilder sqlb = new StringBuilder();
656
				sqlb.append("select srid from spatial_ref_sys where ");
657
				if (abrev.length > 1) {
658
					sqlb.append("auth_name = ? and ");
659
				}
660
				sqlb.append("auth_srid = ?");
661

  
662
				String sql = sqlb.toString();
663
				PreparedStatement st;
664
				try {
665
					st = conn.prepareStatement(sql);
666
				} catch (SQLException e){
667
					throw new JDBCPreparingSQLException(sql,e);
668
				}
669
				ResultSet rs = null;
670
				try{
671
					int i=0;
672
					if (abrev.length > 1){
673
						st.setString(i+1, abrev[i]);
674
						i++;
675
					}
676
					st.setInt(i + 1, Integer.parseInt(abrev[i]));
677

  
678
					try{
679
						rs = JDBCHelper.executeQuery(st,sql); 
680
                                                
681
					} catch (SQLException e){
682
						throw new JDBCExecutePreparedSQLException(sql, abrev, e);
683
					}
684

  
685
					if (!rs.next()) {
686
						return null;
687
					}
688

  
689
					return new Integer(rs.getInt(1));
690

  
691
				} catch (SQLException e){
692
					throw new JDBCSQLException(e);
693
				} finally{
694
					try {rs.close(); } catch (Exception e) {};
695
					try {st.close(); } catch (Exception e) {};
696
				}
697

  
698
			}
699

  
700
		};
701

  
702
		Integer pgSRSID = null;
703
		try {
704
			pgSRSID = (Integer) doConnectionAction(action);
705
		} catch (Exception e) {
706
			logger.error("Excetion searching pgSRS", e);
707
			return -1;
708
		}
709

  
710
		if (pgSRSID != null) {
711
			addToPgSRToSRSID(pgSRSID.intValue(), srsID);
712
			return pgSRSID.intValue();
713
		}
714
		return -1;
715

  
716
	}
717

  
718
	private void addToPgSRToSRSID(int pgSRID, String srsId) {
719
		if (pgSRID < 0 || srsId == null || srsId.length() == 0) {
720
			return;
721
		}
722
		Integer pgSRIDInteger = new Integer(pgSRID);
723
		pgSR2SRSID.put(pgSRIDInteger, srsId);
724
		srsID2pgSR.put(srsId, pgSRIDInteger);
725
	}
726

  
727
        public List<String> getSqlGeometyFieldAdd(FeatureAttributeDescriptor attr,
728
                String table, String schema) {
729
                    // SELECT AddGeometryColumn({schema}, {table}, {field}, {srid}(int),
730
            // {geomType}(Str), {dimensions}(int))
731

  
732
                    // gemoType:
733
                    /*
734
             * POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING,
735
             * MULTIPOLYGON, GEOMETRYCOLLECTION POINTM, LINESTRINGM, POLYGONM,
736
             * MULTIPOINTM, MULTILINESTRINGM, MULTIPOLYGONM, GEOMETRYCOLLECTIONM
737
             */
738
            List<String> sqls = new ArrayList<String>();
739

  
740
            StringBuilder strb = new StringBuilder();
741
            strb.append("SELECT AddGeometryColumn('");
742
            if ( schema != null && schema.length() > 0 ) {
743
                strb.append(schema);
744
                strb.append("', '");
745
            }
746
            strb.append(table);
747
            strb.append("', '");
748
            strb.append(attr.getName().toLowerCase());
749
            strb.append("', ");
750
            strb.append(getProviderSRID(attr.getSRS()));
751
            strb.append(", '");
752

  
753
            strb.append(getPostgisGeomType(
754
                    attr.getGeometryType(),
755
                    attr.getGeometrySubType()
756
            )
757
            );
758
            strb.append("', ");
759
            strb.append(getPostgisGeomDimensions(attr.getGeometrySubType()));
760
            strb.append(")");
761

  
762
            sqls.add(strb.toString());
763

  
764
            return sqls;
765
        }
766

  
767
	public String getSqlFieldName(FeatureAttributeDescriptor attribute) {
768
		if (attribute.getType() == DataTypes.GEOMETRY) {
769
			return getFunctionName("ST_AsBinary") + "("
770
			    + super.getSqlFieldName(attribute) + ")";
771
		}
772
		return super.getSqlFieldName(attribute);
773
	}
774

  
775
	protected EditableFeatureAttributeDescriptor createAttributeFromJDBC(
776
			EditableFeatureType type, Connection conn,
777
			ResultSetMetaData rsMetadata, int colIndex) throws SQLException {
778
		if (rsMetadata.getColumnType(colIndex) == java.sql.Types.OTHER) {
779
			if (rsMetadata.getColumnTypeName(colIndex).equalsIgnoreCase(
780
					"geometry")) {
781
				EditableFeatureAttributeDescriptor attr = type.add(rsMetadata.getColumnName(colIndex),
782
						DataTypes.GEOMETRY);
783
				// Set default values for geometry type
784
		                attr.setGeometryType(Geometry.TYPES.GEOMETRY);
785
		                attr.setGeometrySubType(Geometry.SUBTYPES.GEOM2D);
786
		                return attr;
787

  
788
			}
789
		}
790

  
791
		return super.createAttributeFromJDBC(type, conn, rsMetadata, colIndex);
792
	}
793

  
794
	public List getAdditionalSqlToCreate(NewDataStoreParameters ndsp,
795
			FeatureType fType) {
796
		FeatureAttributeDescriptor attr;
797
		Iterator iter = fType.iterator();
798
		List result = new ArrayList();
799
		PostgreSQLNewStoreParameters pgNdsp = (PostgreSQLNewStoreParameters) ndsp;
800
		while (iter.hasNext()){
801
			attr = (FeatureAttributeDescriptor) iter.next();
802
			if (attr.getType() == DataTypes.GEOMETRY){
803
				result.addAll(getSqlGeometyFieldAdd(attr, pgNdsp.getTable(),
804
						pgNdsp
805
						.getSchema()));
806
			}
807
                        if( attr.isIndexed() ) {
808
                            result.add(getCreateIndexStatement((JDBCNewStoreParameters) ndsp, attr));
809
                        }
810
                        if( attr.isAutomatic() ) {
811
                            // A?adimos los GRANT para la secuencia asociada a la tabla.
812
                            String table = "\""+pgNdsp.getSchema() +"\".\""+pgNdsp.getTable()+"_"+attr.getName()+"_seq\" ";
813
                            result.addAll(this.createGrantStatements(pgNdsp, table));
814
                        }
815
		}
816

  
817
              
818
		return result;
819
	}
820

  
821
        protected String getCreateIndexStatement(JDBCNewStoreParameters params,FeatureAttributeDescriptor attr ) {
822
            String indexName = "idx_"+params.getTable()+"_"+attr.getName();
823
            
824
            String statement = "CREATE ";
825
            if( !attr.allowIndexDuplicateds() ) {
826
                statement += " UNIQUE ";
827
            }
828
            statement += "INDEX \""+indexName+"\" ";
829
            statement += "ON " + params.tableID() + " ";
830
            if( attr.getType()==DataTypes.GEOMETRY ) {
831
                statement += " USING GIST ";
832
                statement += "( \"" + attr.getName()+ "\")";
833
            } else {
834
                statement += "( \"" + attr.getName()+ "\"";
835
                if( attr.isIndexAscending() ) {
836
                    statement += " ASC )";
837
                } else {
838
                    statement += " DESC )";
839
                }
840
            }
841
            return statement;
842
        }
843
        
844
	public String getSqlFieldDescription(FeatureAttributeDescriptor attr)
845
			throws DataException {
846
		if (attr.getType() == DataTypes.GEOMETRY){
847
			return null;
848
		}
849
		return super.getSqlFieldDescription(attr);
850
	}
851

  
852

  
853
	public boolean allowAutomaticValues() {
854
		return Boolean.TRUE;
855
	}
856

  
857
	public boolean supportOffset() {
858
		return true;
859
	}
860

  
861
	public boolean supportsUnion() {
862
		return true;
863
	}
864
	
865
	public String escapeFieldName(String field) {
866
		/*
867
		if (!reservedWord(field) && 
868
				field.matches("[a-z][a-z0-9_]*")) {
869
			return field;
870
		}
871
		*/
872
		String quote = getIdentifierQuoteString();
873
		return quote + field + quote;
874
	}
875
	
876
    protected EditableFeatureAttributeDescriptor createAttributeFromJDBCNativeType(
877
        EditableFeatureType fType, ResultSetMetaData rsMetadata, int colIndex)
878
        throws SQLException {
879

  
880
        EditableFeatureAttributeDescriptor column;
881

  
882
        String nativeType = rsMetadata.getColumnTypeName(colIndex);
883

  
884
        if (nativeType.startsWith("int")) {
885
            column = fType.add(rsMetadata.getColumnName(colIndex),
886
                DataTypes.INT);
887
            column.setAdditionalInfo("SQLType", new Integer(rsMetadata
888
                .getColumnType(colIndex)));
889
            column.setAdditionalInfo("SQLTypeName", rsMetadata
890
                .getColumnTypeName(colIndex));
891
            return column;
892
        }
893
        return super.createAttributeFromJDBCNativeType(fType, rsMetadata, colIndex);
894
    }
895

  
896
    public Object dalValueToJDBC(
897
        FeatureAttributeDescriptor attributeDescriptor, Object object)
898
        throws WriteException {
899
           if ("int2".equals(attributeDescriptor.getAdditionalInfo("SQLTypeName"))) {
900
                return new Short(String.valueOf(object));
901
            }
902

  
903
        return super.dalValueToJDBC(attributeDescriptor, object);
904
    }
905
    
906
    // =======================================
907
    
908

  
909
    public String getFunctionName(String newFuncName) {
910
        
911
        if (!versionSet) {
912
            postGISVersion = getPostgisVersion();
913
            versionSet = true;
914
        }
915
        return getFunctionNameForVersion(newFuncName, postGISVersion);
916
    }
917

  
918
    private String getFunctionNameForVersion(String newFuncName, int[] pv) {
919
        
920
        if (newFuncName == null || pv == null) {
921
            return newFuncName;
922
        }
923
        
924
        if (pv.length < 2) {
925
            // cannot compare
926
            return newFuncName;
927
        }
928
        
929
        if (pv[0] > 1) {
930
            return newFuncName;
931
        }
932
        
933
        if (pv[0] == 1 && pv[1] >= 3) {
934
            return newFuncName;
935
        }
936
        
937
        Properties pp = this.getBeforePostgis13Properties();
938
        String k = newFuncName.toLowerCase();
939
        String v = pp.getProperty(k);
940
        if (v == null) {
941
            return newFuncName;
942
        } else {
943
            return v;
944
        }
945
    }
946

  
947

  
948
    private int[] getPostgisVersion() {
949

  
950
        String sql = "SELECT PostGIS_Lib_Version()";
951
        ResultSet rs = null;
952
        Statement st = null;
953
        String v = null;
954
        Connection conn = null;
955
        try {
956
            conn = this.getConnection();
957
            st = conn.createStatement();
958
            rs = JDBCHelper.executeQuery(st,sql); 
959
            rs.next();
960
            v = rs.getString(1);
961
            if (v == null) {
962
                throw new Exception("Returned version is NULL");
963
            }
964
        } catch (Exception exc) {
965
            logger.error("Unable to get Postgis version: " + exc.getMessage(), exc);
966
            return null;
967
        } finally {
968
            try { rs.close(); } catch (Exception e) {};
969
            try { st.close(); } catch (Exception e) {};
970
            try { conn.close(); } catch (Exception e) {};
971
        }
972

  
973
        String[] vv = v.split("\\.");
974
        int[] resp = new int[3];
975
        try {
976
            for (int i=0; i<3; i++) {
977
                resp[i] = Integer.parseInt(vv[i]);
978
            }
979
        } catch (Exception exc) {
980
            logger.error("Unable to parse version: " + v, exc);
981
            return null;
982
        }
983
        return resp;
984
    }
985
    
986
    
987
    
988
    protected Properties getBeforePostgis13Properties() {
989
        if (beforePostgis13 == null) {
990
            
991
            beforePostgis13 = new Properties();
992
            // Left side MUST be in lower case
993
            // Right side will be used if Postgis version < 1.3
994
            beforePostgis13.setProperty("st_intersects", "Intersects");
995
            beforePostgis13.setProperty("st_extent", "Extent");
996
            beforePostgis13.setProperty("st_envelope", "Envelope");
997
            beforePostgis13.setProperty("st_asbinary", "AsBinary");
998
            beforePostgis13.setProperty("st_geomfromtext", "GeomFromText");
999
            beforePostgis13.setProperty("st_geomfromwkb", "GeomFromWKB");
1000
        }
1001
        return beforePostgis13;
1002
    }
1003
    
1004

  
1005

  
1006
}
tags/org.gvsig.postgresql-2.0.37/org.gvsig.postgresql.provider/src/main/java/org/gvsig/fmap/dal/store/postgresql/PostgreSQLStoreParameters.java
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
package org.gvsig.fmap.dal.store.postgresql;
29

  
30
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
31
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
32

  
33
public class PostgreSQLStoreParameters extends JDBCStoreParameters implements
34
		PostgreSQLConnectionParameters {
35
    public static final String PARAMETERS_DEFINITION_NAME = "PostgreSQLStoreParameters";
36

  
37

  
38
	public PostgreSQLStoreParameters() {
39
		super(PARAMETERS_DEFINITION_NAME, PostgreSQLStoreProvider.NAME);
40
	}
41

  
42
	public PostgreSQLStoreParameters(String parametersDefinitionName) {
43
		super(parametersDefinitionName, PostgreSQLStoreProvider.NAME);
44
	}
45

  
46
	public Boolean getUseSSL() {
47
		return (Boolean) this.getDynValue(DYNFIELDNAME_USESSL);
48
	}
49

  
50
	public void setUseSSL(Boolean useSSL) {
51
		this.setDynValue(DYNFIELDNAME_USESSL, useSSL);
52
	}
53

  
54
	public void setUseSSL(boolean useSSL) {
55
		this.setDynValue(DYNFIELDNAME_USESSL, new Boolean(useSSL));
56
	}
57

  
58

  
59
	public void validate() throws ValidateDataParametersException {
60
		if (getJDBCDriverClassName() == null) {
61
			setJDBCDriverClassName(PostgreSQLLibrary.DEFAULT_JDCB_DRIVER_NAME);
62
		}
63
		if (getUrl() == null) {
64
			setUrl(PostgreSQLLibrary.getJdbcUrl(getHost(), getPort(),
65
					getDBName()));
66
		}
67

  
68
		if (getPort() == null) {
69
			setPort(new Integer(5432));
70
		}
71
		super.validate();
72
	}
73

  
74
}
tags/org.gvsig.postgresql-2.0.37/org.gvsig.postgresql.provider/src/main/java/org/gvsig/fmap/dal/store/postgresql/PostgreSQLConnectionParameters.java
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 org.gvsig.fmap.dal.store.jdbc.JDBCConnectionParameters;
34

  
35
/**
36
 * @author jmvivo
37
 *
38
 */
39
public interface PostgreSQLConnectionParameters extends
40
		JDBCConnectionParameters {
41

  
42
	public static final String DYNFIELDNAME_USESSL = "UseSSL";
43

  
44
	public Boolean getUseSSL();
45
}
tags/org.gvsig.postgresql-2.0.37/org.gvsig.postgresql.provider/src/main/java/org/gvsig/fmap/dal/store/postgresql/PostgreSQLLibrary.java
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
* 2008 IVER T.I. S.A.   {{Task}}
26
*/
27

  
28
package org.gvsig.fmap.dal.store.postgresql;
29

  
30
import org.gvsig.fmap.dal.DALLibrary;
31
import org.gvsig.fmap.dal.DALLocator;
32
import org.gvsig.fmap.dal.resource.spi.ResourceManagerProviderServices;
33
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
34
import org.gvsig.fmap.dal.store.db.DBHelper;
35
import org.gvsig.fmap.dal.store.jdbc.JDBCLibrary;
36
import org.gvsig.metadata.exceptions.MetadataException;
37
import org.gvsig.tools.library.AbstractLibrary;
38
import org.gvsig.tools.library.LibraryException;
39

  
40
public class PostgreSQLLibrary extends AbstractLibrary {
41

  
42
	static String DEFAULT_JDCB_DRIVER_NAME = "org.postgresql.Driver";
43

  
44
    @Override
45
    public void doRegistration() {
46
        registerAsServiceOf(DALLibrary.class);
47
        require(JDBCLibrary.class);
48
    }
49

  
50
	public static String getJdbcUrl(String host, Integer port, String db) {
51
		String url = null;
52
		if(host != null){
53
		    String sport = "";
54
		    if (port != null) {
55
		        sport = ":" + port;
56
		    }
57
		    url = "jdbc:postgresql://" + host + sport + "/" + db;
58
		}
59
		return url;
60
	}
61

  
62

  
63
	@Override
64
	protected void doInitialize() throws LibraryException {
65
	}
66

  
67

  
68
	@Override
69
	protected void doPostInitialize() throws LibraryException {
70
		LibraryException ex=null;
71

  
72
		new JDBCLibrary().postInitialize();
73

  
74
		 DBHelper.registerParametersDefinition(
75
				 PostgreSQLStoreParameters.PARAMETERS_DEFINITION_NAME,
76
				 PostgreSQLStoreParameters.class,
77
				 "PostgreSQLParameters.xml"
78
		);
79
		DBHelper.registerParametersDefinition(
80
				PostgreSQLNewStoreParameters.PARAMETERS_DEFINITION_NAME,
81
				PostgreSQLNewStoreParameters.class,
82
				"PostgreSQLParameters.xml"
83
		);
84
		DBHelper.registerParametersDefinition(
85
				PostgreSQLServerExplorerParameters.PARAMETERS_DEFINITION_NAME, 
86
				PostgreSQLServerExplorerParameters.class, 
87
				"PostgreSQLParameters.xml"
88
		);
89
		DBHelper.registerParametersDefinition(
90
				PostgreSQLResourceParameters.PARAMETERS_DEFINITION_NAME, 
91
				PostgreSQLResourceParameters.class, 
92
				"PostgreSQLParameters.xml"
93
		);
94
		try {
95
			DBHelper.registerMetadataDefinition(
96
					PostgreSQLStoreProvider.METADATA_DEFINITION_NAME, 
97
					PostgreSQLStoreProvider.class, 
98
					"PostgreSQLMetadata.xml"
99
			);
100
		} catch (MetadataException e) {
101
			ex = new LibraryException(this.getClass(),e);
102
		}
103
		
104
		ResourceManagerProviderServices resman = (ResourceManagerProviderServices) DALLocator
105
		.getResourceManager();
106

  
107
		
108
		if (!resman.getResourceProviders().contains(PostgreSQLResource.NAME)) {
109
			resman.register(PostgreSQLResource.NAME,
110
					PostgreSQLResource.DESCRIPTION, PostgreSQLResource.class,
111
					PostgreSQLResourceParameters.class);
112
		}
113
		
114
		
115
		DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator
116
				.getDataManager();
117
		
118
		if (!dataman.getStoreProviders().contains(PostgreSQLStoreProvider.NAME)) {
119
			dataman.registerStoreProvider(PostgreSQLStoreProvider.NAME,
120
					PostgreSQLStoreProvider.class,
121
					PostgreSQLStoreParameters.class);
122
		}
123
		
124
		if (!dataman.getExplorerProviders().contains(
125
				PostgreSQLStoreProvider.NAME)) {
126
			dataman.registerExplorerProvider(PostgreSQLServerExplorer.NAME,
127
					PostgreSQLServerExplorer.class,
128
					PostgreSQLServerExplorerParameters.class);
129
		}
130
		if( ex!=null ) {
131
			throw ex;
132
		}
133
	}
134

  
135
}
tags/org.gvsig.postgresql-2.0.37/org.gvsig.postgresql.provider/src/main/java/org/gvsig/fmap/dal/store/postgresql/PostgreSQLSetProvider.java
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.util.ArrayList;
34
import java.util.List;
35

  
36
import org.cresques.cts.IProjection;
37
import org.slf4j.Logger;
38
import org.slf4j.LoggerFactory;
39

  
40
import org.gvsig.fmap.dal.exception.DataException;
41
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
42
import org.gvsig.fmap.dal.feature.FeatureQuery;
43
import org.gvsig.fmap.dal.feature.FeatureStore;
44
import org.gvsig.fmap.dal.feature.FeatureType;
45
import org.gvsig.fmap.dal.feature.exception.CreateGeometryException;
46
import org.gvsig.fmap.dal.store.db.DBStoreParameters;
47
import org.gvsig.fmap.dal.store.jdbc.JDBCSetProvider;
48
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreProvider;
49
import org.gvsig.fmap.geom.primitive.Envelope;
50
import org.gvsig.tools.evaluator.Evaluator;
51
import org.gvsig.tools.evaluator.EvaluatorFieldValue;
52
import org.gvsig.tools.evaluator.EvaluatorFieldsInfo;
53

  
54
/**
55
 * @author jmvivo
56
 *
57
 */
58
public class PostgreSQLSetProvider extends JDBCSetProvider {
59

  
60
    private static Logger logger = LoggerFactory.getLogger(PostgreSQLSetProvider.class);
61
    
62
	public PostgreSQLSetProvider(JDBCStoreProvider store, FeatureQuery query,
63
			FeatureType featureType) throws DataException {
64
		super(store, query, featureType);
65
	}
66

  
67

  
68
	/*
69
	 * (non-Javadoc)
70
	 *
71
	 * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#canFilter()
72
	 */
73
	public boolean canFilter() {
74
		// TODO more checks
75
		if (!super.canFilter()) {
76
			return false;
77
		}
78
		return true;
79

  
80
	}
81
	
82
    protected String getSqlForEvaluator(Evaluator filter) {
83
        
84
        String resp = null;
85
        if (filter != null && filter.getSQL() != null) {
86
            // =================================================
87
            EvaluatorFieldsInfo info = filter.getFieldsInfo();
88
            String filterString = filter.getSQL();
89
            
90
            String[] filterNames = null;
91
            String[] finalNames = null;
92
            
93
            if (info == null) {
94
                filterNames = getFieldNames(getFeatureType());
95
            } else {
96
                filterNames = info.getFieldNames();
97
            }
98
            
99
            finalNames = new String[filterNames.length];
100
            FeatureAttributeDescriptor attr;
101
            for (int i = 0; i < filterNames.length; i++) {
102
                attr = getFeatureType().getAttributeDescriptor(filterNames[i]);
103
                if (attr == null) {
104
                    finalNames[i] = filterNames[i];
105
                    continue;
106
                }
107
                finalNames[i] = getEscapedFieldName(attr.getName());
108
            }
109

  
110
            for (int i = 0; i < filterNames.length; i++) {
111
                if (!filterNames[i].equals(finalNames[i])) {
112
                    filterString = filterString.replaceAll(
113
                            "\\b" + filterNames[i] + "\\b",
114
                            finalNames[i]);
115
                }
116
            }
117
            resp = filterString;        
118
        }
119
        // ================================
120
        // In any case, append working area filter
121
        
122
        try {
123
            resp = appendWorkingAreaCondition(resp);
124
        } catch (Exception e) {
125
            logger.error("While appending working area condition.", e);
126
        }
127
        return resp;
128
    }	
129
    
130
    private String[] getFieldNames(FeatureType ft) {
131
        
132
        if (ft == null) {
133
            return new String[0];
134
        }
135
        FeatureAttributeDescriptor[] atts = ft.getAttributeDescriptors();
136
        String[] resp = new String[atts.length];
137
        for (int i=0; i<atts.length; i++) {
138
            resp[i] = atts[i].getName();
139
        }
140
        return resp;
141
    }
142
    
143
    private String getFunctionName(String newFunctionName) {
144
        
145
        PostgreSQLStoreProvider pg_sto_prov = (PostgreSQLStoreProvider) this.getStore();
146
        PostgreSQLHelper hpr = pg_sto_prov.getPgHelper();
147
        if (hpr == null) {
148
            logger.info("Unable to get PG helper.", new Exception("Helper is null"));
149
            return newFunctionName;
150
        } else {
151
            return hpr.getFunctionName(newFunctionName);
152
        }
153
    }
154

  
155

  
156
    private String appendWorkingAreaCondition(String sql) throws Exception {
157
        
158
        
159
        DBStoreParameters dbParams = 
160
        (DBStoreParameters) getStore().getParameters();
161
        
162
        Envelope wa = dbParams.getWorkingArea(); 
163
        if (wa == null) {
164
            return sql;
165
        } else {
166
            
167
            FeatureStore fstore = this.getStore().getFeatureStore();
168
            String geoname =
169
                fstore.getDefaultFeatureType().getDefaultGeometryAttributeName();
170
            
171
            StringBuffer strbuf = new StringBuffer();
172
            
173
            if (sql == null)  {
174
                strbuf.append(
175
                    getFunctionName("ST_Intersects") + "("
176
                    + getFunctionName("ST_GeomFromText") + "('");
177
            } else {
178
                strbuf.append("(");
179
                strbuf.append(sql);
180
                strbuf.append(") AND "
181
                    + getFunctionName("ST_Intersects") + "("
182
                    + getFunctionName("ST_GeomFromText") + "('");
183
            }
184
            
185
            String workAreaWkt = null;
186
            workAreaWkt = wa.getGeometry().convertToWKT();
187
            strbuf.append(workAreaWkt);
188
            strbuf.append("', ");
189
            
190
            PostgreSQLStoreProvider sprov = (PostgreSQLStoreProvider) getStore();
191
            PostgreSQLHelper helper = sprov.getPgHelper();
192
            
193
            IProjection proj = dbParams.getCRS();
194
            int sridInt = helper.getProviderSRID(proj); 
195
            if (sridInt == -1) {
196
                throw new CreateGeometryException(
197
                        new Exception("CRS is null or unknown."));
198
            } else {
199
                strbuf.append(Integer.toString(sridInt));
200
            }
201
            strbuf.append("), " + getFunctionName("ST_Envelope") + "(");
202
            strbuf.append(helper.escapeFieldName(geoname));
203
            strbuf.append("))");
204
            
205
            return strbuf.toString();
206
        }
207
    }
208
	
209

  
210
}
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff