Revision 20029 trunk/libraries/libDataSourceDBBaseDrivers/src/org/gvsig/data/datastores/vectorial/db/jdbc/postgresql/PostgresqlStoreUtils.java

View differences:

PostgresqlStoreUtils.java
1 1
package org.gvsig.data.datastores.vectorial.db.jdbc.postgresql;
2 2

  
3
import java.math.BigDecimal;
4
import java.nio.ByteBuffer;
5 3
import java.sql.Connection;
6
import java.sql.Date;
7 4
import java.sql.DriverManager;
8 5
import java.sql.ResultSet;
9 6
import java.sql.ResultSetMetaData;
10 7
import java.sql.Statement;
11
import java.sql.Timestamp;
12
import java.sql.Types;
8
import java.util.ArrayList;
13 9
import java.util.Iterator;
14 10

  
15 11
import org.gvsig.data.datastores.vectorial.db.DBFeatureType;
......
18 14
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCStore;
19 15
import org.gvsig.data.datastores.vectorial.db.jdbc.exception.JDBCDriverNotFoundException;
20 16
import org.gvsig.data.datastores.vectorial.db.jdbc.exception.SQLException;
21
import org.gvsig.data.datastores.vectorial.db.jdbc.h2.H2Store;
22 17
import org.gvsig.data.exception.InitializeException;
23 18
import org.gvsig.data.exception.ReadException;
24 19
import org.gvsig.data.vectorial.DefaultAttributeDescriptor;
25 20
import org.gvsig.data.vectorial.IFeature;
26 21
import org.gvsig.data.vectorial.IFeatureAttributeDescriptor;
22
import org.postgis.PGgeometry;
27 23

  
28 24
import com.iver.cit.gvsig.fmap.core.IGeometry;
25
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
29 26
import com.iver.cit.gvsig.fmap.drivers.WKBParser2;
30
import com.iver.cit.gvsig.fmap.drivers.XTypes;
31
import com.vividsolutions.jts.io.WKBWriter;
32 27

  
33 28
public class PostgresqlStoreUtils {
34 29

  
35
	private static WKBParser2 wkbParser = new WKBParser2();
36
	private static WKBWriter wkbWriter = new WKBWriter();
37

  
38

  
39 30
	static String getJDBCUrl(String host, String db, String port) {
40 31
		String url;
41 32
		url = "jdbc:postgresql://"+host+":" + port +"/"+db;
......
43 34
		return url;
44 35
	}
45 36

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

  
45
		sqlSeq.append("  and table_catalog = '" + attr.getCatalogName()+ "'");
46
		sqlSeq.append(")");
47

  
48
	}
49

  
50
	private static void initializeSerialFields(Connection connection,DBFeatureType featureType) throws java.sql.SQLException{
51
		JDBCAttributeDescriptor attr;
52

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

  
79

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

  
94
		}
95

  
96

  
97
	}
98

  
99

  
46 100
	static DBFeatureType getFeatureType(Connection connection, PostgresqlStoreParameters params) throws ReadException{
47 101
		DBFeatureType featureType = new DBFeatureType();
102
		String[] ids =params.getFieldsId();
103
		int i;
48 104

  
49 105

  
50 106
		loadFieldsToFeatureType(connection, params, featureType);
51 107

  
52 108

  
53
		featureType.setFieldsId(params.getFieldsId());
109
		//Inicializamos los IDs
110
		JDBCAttributeDescriptor attr;
111
		for (i=0;i<ids.length;i++){
112
			try {
113
				attr = (JDBCAttributeDescriptor)featureType.get(ids[i]);
114
			} catch (IndexOutOfBoundsException e){
115
				throw new InitializeException(
116
						PostgresqlStore.DATASTORE_NAME,
117
						new Exception("Id Field '"+ ids[i] +"' not Found"));
54 118

  
119
			}
120
			attr.setPrimaryKey(true);
121
		}
122
		featureType.setFieldsId(ids);
123

  
124
		//Inicializamos los 'serial' ya que en postgres el
125
		//'isAutonumeric' devuelve false
126
//		try{
127
//			initializeSerialFields(connection,featureType);
128
//		} catch (java.sql.SQLException e) {
129
//			throw new InitializeException(PostgresqlStore.DATASTORE_NAME,e);
130
//
131
//		}
132
//
133

  
134

  
135

  
136

  
137
		//Inicializar campos geometricos si los hubiese
138
		//TODO Datos geometricos
139

  
140

  
141
		//Inicializar la geometria por defecto
55 142
		if (params.getDefaultGeometryField() != null && params.getDefaultGeometryField() != ""){
56 143
			if (featureType.getFieldIndex(params.getDefaultGeometryField())< 0){
57
				// FIXME: crear una nueva excepcion??
58 144
				throw new InitializeException(
59 145
						PostgresqlStore.DATASTORE_NAME,
60 146
						new Exception("Geometry Field '"+ params.getDefaultGeometryField() +"' not Found"));
61 147

  
62 148
			}
149
			attr = (JDBCAttributeDescriptor)featureType.get(params.getDefaultGeometryField());
150
			if (attr.getDataType() != IFeatureAttributeDescriptor.TYPE_GEOMETRY){
151
				throw new InitializeException(
152
						PostgresqlStore.DATASTORE_NAME,
153
						new Exception("Field '"+ params.getDefaultGeometryField() +"' isn't a geometry"));
63 154

  
155
			}
156

  
64 157
			featureType.setDefaultGeometry(params.getDefaultGeometryField());
65 158
		}
66 159

  
160

  
67 161
		return featureType;
68 162

  
69 163
	}
......
71 165
	private static void loadFieldsToFeatureType(Connection conn,PostgresqlStoreParameters params,DBFeatureType featureType) throws ReadException{
72 166
		String sql="";
73 167
		String columns=params.getFieldsString();
168
		boolean fillTableData;
74 169

  
75 170
		if (params.getSqlSoure() != null){
76 171
			sql = params.getSqlSoure();
172
			fillTableData = false;
77 173
		} else {
78
			sql = "Select "+columns+" from " + params.tableID() + " limit 1;";
174
			sql = "Select "+columns+" from " + params.tableID();
175
			fillTableData = true;
79 176
		}
80 177

  
81 178
		try {
82 179

  
83 180
			Statement stAux = conn.createStatement();
181
			stAux.setFetchSize(1);
84 182
			ResultSet rs = stAux.executeQuery(sql);
85 183
			ResultSetMetaData rsMetadata = rs.getMetaData();
86 184

  
87 185
			int i;
88 186

  
89 187
			featureType.setTableID(params.tableID());
90
			DefaultAttributeDescriptor attr;
188
			JDBCAttributeDescriptor attr;
91 189
			for (i=1;i<=rsMetadata.getColumnCount();i++){
92 190
				attr = getAttributeFromJDBC(conn,rsMetadata,i);
93 191
				featureType.add(attr);
94 192
				attr.setOrdinal(i-1);
193
				attr.setCatalogName(params.getDb());
194
				if (fillTableData){
195
					attr.setSchemaName(params.getSchema());
196
					attr.setTableName(params.getTableName());
197

  
198
				}
95 199
			}
96 200
			rs.close();
201
			stAux.close();
202

  
203

  
204

  
97 205
		} catch (java.sql.SQLException e) {
98
			// TODO Auto-generated catch block
99 206
			throw new SQLException(sql,"getFeatureType",e);
100 207
		}
101 208

  
102 209
	}
103 210

  
104
	private static DefaultAttributeDescriptor getAttributeFromJDBC(Connection conn,ResultSetMetaData rsMetadata,int colIndex) throws SQLException{
211
	private static JDBCAttributeDescriptor getAttributeFromJDBC(Connection conn,ResultSetMetaData rsMetadata,int colIndex) throws SQLException{
105 212
		JDBCAttributeDescriptor column= new JDBCAttributeDescriptor();
106 213
		try {
107 214
			column.setName(rsMetadata.getColumnName(colIndex));
215
			column.setCaseSensitive(rsMetadata.isCaseSensitive(colIndex));
108 216
			column.setSqlType(rsMetadata.getColumnType(colIndex));
109 217
			column.setAllowNull(rsMetadata.isNullable(colIndex) == ResultSetMetaData.columnNullable);
110 218
			column.setAutoIncrement(rsMetadata.isAutoIncrement(colIndex));
111 219
			column.setReadOnly(rsMetadata.isReadOnly(colIndex));
220
			column.setWritable(rsMetadata.isWritable(colIndex));
221
			column.setClassName(rsMetadata.getColumnClassName(colIndex));
222
			column.setCatalogName(rsMetadata.getCatalogName(colIndex));
223
			column.setDefinitelyWritable(rsMetadata.isDefinitelyWritable(colIndex));
224
			column.setLabel(rsMetadata.getColumnLabel(colIndex));
225
			column.setSchemaName(rsMetadata.getSchemaName(colIndex));
226
			column.setTableName(rsMetadata.getTableName(colIndex));
227
			column.setCatalogName(rsMetadata.getCatalogName(colIndex));
228
			column.setSqlTypeName(rsMetadata.getColumnTypeName(colIndex));
229
			column.setSearchable(rsMetadata.isSearchable(colIndex));
230
			column.setSigned(rsMetadata.isSigned(colIndex));
231
			column.setCurrency(rsMetadata.isCurrency(colIndex));
232
			column.setPrecision(rsMetadata.getPrecision(colIndex));
233
			column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
112 234

  
235

  
113 236
			switch (rsMetadata.getColumnType(colIndex)) {
114 237
			case java.sql.Types.INTEGER:
115 238
				column.setType(IFeatureAttributeDescriptor.TYPE_INT);
......
119 242
				break;
120 243
			case java.sql.Types.REAL:
121 244
				column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
122
				column.setPrecision(rsMetadata.getPrecision(colIndex));
123 245
				break;
124 246
			case java.sql.Types.DOUBLE:
125 247
				column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
126
				column.setPrecision(rsMetadata.getPrecision(colIndex));
127 248
				break;
128 249
			case java.sql.Types.CHAR:
129 250
				column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
130
				column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
131 251
				break;
132 252
			case java.sql.Types.VARCHAR:
133 253
				column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
134
				column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
135 254
				break;
136 255
			case java.sql.Types.FLOAT:
137 256
				column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
138
				column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
139
				column.setPrecision(rsMetadata.getPrecision(colIndex));
140 257
				break;
141 258
			case java.sql.Types.DECIMAL:
142 259
				column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
143
				column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
144
				column.setPrecision(rsMetadata.getPrecision(colIndex));
145 260
				break;
146 261
			case java.sql.Types.DATE:
147 262
				column.setType(IFeatureAttributeDescriptor.TYPE_DATE);
......
149 264
			case java.sql.Types.BOOLEAN:
150 265
				column.setType(IFeatureAttributeDescriptor.TYPE_BOOLEAN);
151 266
				break;
267
			case java.sql.Types.OTHER:
268
				if (column.getSqlTypeName().equalsIgnoreCase("geometry")){
269
					column.setType(IFeatureAttributeDescriptor.TYPE_GEOMETRY);
270
					break;
271
				}
272
				//No hacemos break para que se quede en default
273

  
152 274
			default:
153 275
				column.setType(IFeatureAttributeDescriptor.TYPE_OBJECT);
154 276
				break;
......
162 284
	}
163 285

  
164 286

  
165
	static String getFliterForID(DBFeatureType featureType, Object[] featureKey) {
166
		// TODO Auto-generated method stub
167
		return null;
287
	static String getFilterForID(DBFeatureType fType, IFeature feature){
288
		return getFilterForID(fType, getPkFromFeature(feature,fType));
168 289
	}
169 290

  
291
	static String getFilterForID(DBFeatureType fType, Object[] featureKey){
292
		//TODO: Ojo para los multiples
293
		if (fType.getFieldsId().length != 1)
294
			throw new UnsupportedOperationException("ID fields > 1");
295
		String id =fType.getFieldsId()[0];
296
		return id + " = " + objectToSqlString(featureKey[0]);
297
	}
298

  
299
	static String objectToSqlString(Object obj){
300
		if (obj instanceof String){
301
			return "'"+ scapeString((String)obj) +"'";
302
		} else if (obj == null){
303
			return "null";
304
		}else{
305
			// OJO con otros tipos!!
306
			return obj.toString();
307
		}
308

  
309
	}
310

  
311
	static String scapeString(String str){
312
		return str.replace("'", "''");
313
	}
314

  
315

  
316

  
170 317
	static Connection getConnection(String dbUrl, String dbUser, String dbPass) throws InitializeException {
171 318
		//TODO: Aqu? habria que implementar la llamada
172 319
		//      al Resource Manager para comprobar si ya hay
......
202 349
	}
203 350

  
204 351

  
205
	protected static String getFliterForID(DBFeatureType fType, IFeature feature){
206
		return getFliterForID(fType, getPkFromFeature(feature,fType));
207
	}
208 352

  
209

  
210 353
	protected static Object[] getPkFromResulset(ResultSet rs, DBFeatureType featureType) throws java.sql.SQLException{
211 354
		String[] fieldsId = featureType.getFieldsId();
212 355
		Object[] result = new Object[fieldsId.length];
......
245 388
			while (iter.hasNext()) {
246 389
				IFeatureAttributeDescriptor fad=(IFeatureAttributeDescriptor)iter.next();
247 390
				if (fad.getDataType().equals(IFeatureAttributeDescriptor.TYPE_GEOMETRY)) {
248
					byte[] data = rs.getBytes(fad.getName());
249 391

  
392
					PGgeometry data =(PGgeometry)rs.getObject(fad.getName());
250 393
					if (data == null) {
251 394
						geom = null;
252 395
					} else{
253
						geom = wkbParser.parse(data);
396
						geom = PostGIS2Geometry.getGeneralPath(data);
254 397
					}
255 398
					feature.setGeometry(fad.getName(),geom);
256 399
				} else {

Also available in: Unified diff