Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libDataSourceDBBaseDrivers / src / org / gvsig / data / datastores / vectorial / db / jdbc / h2 / H2Utils.java @ 20029

History | View | Annotate | Download (15 KB)

1
package org.gvsig.data.datastores.vectorial.db.jdbc.h2;
2

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

    
11
import org.gvsig.data.datastores.vectorial.db.DBFeatureType;
12
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCAttributeDescriptor;
13
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCFeature;
14
import org.gvsig.data.datastores.vectorial.db.jdbc.JDBCStore;
15
import org.gvsig.data.datastores.vectorial.db.jdbc.exception.JDBCDriverNotFoundException;
16
import org.gvsig.data.datastores.vectorial.db.jdbc.exception.SQLException;
17
import org.gvsig.data.exception.InitializeException;
18
import org.gvsig.data.exception.ReadException;
19
import org.gvsig.data.vectorial.DefaultAttributeDescriptor;
20
import org.gvsig.data.vectorial.IFeature;
21
import org.gvsig.data.vectorial.IFeatureAttributeDescriptor;
22
import org.gvsig.data.vectorial.IFeatureType;
23

    
24
import com.iver.cit.gvsig.fmap.core.FShape;
25
import com.iver.cit.gvsig.fmap.core.IGeometry;
26
import com.iver.cit.gvsig.fmap.drivers.WKBParser2;
27
import com.vividsolutions.jts.io.WKBWriter;
28

    
29
public class H2Utils {
30
        private static WKBParser2 wkbParser = new WKBParser2();
31

    
32
        static String getFilterForID(DBFeatureType fType, IFeature feature){
33
                return getFilterForID(fType, getPkFromFeature(feature,fType));
34
        }
35

    
36
        static String getFilterForID(DBFeatureType fType, Object[] featureKey){
37
                //TODO: Ojo para los multiples
38
                if (fType.getFieldsId().length != 1)
39
                        throw new UnsupportedOperationException("ID fields > 1");
40
                String id =fType.getFieldsId()[0];
41
                return id + " = " + objectToSqlString(featureKey[0]);
42
        }
43

    
44
        static String getDefaultSchema(Connection conn, String catalog) throws InitializeException {
45
                String sql= "SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE IS_DEFAULT = TRUE";
46
                if (catalog == null || catalog ==""){
47
                        sql= sql+ " AND CATALOG_NAME = '"+catalog+"'";
48
                }
49

    
50
                String schema = null;
51
                Statement st = null;
52
                ResultSet rs= null;
53
                try{
54
                        st = conn.createStatement(ResultSet.FETCH_FORWARD, ResultSet.CONCUR_READ_ONLY);
55
                        rs = st.executeQuery(sql);
56
                        if (!rs.next()){
57
                                throw new InitializeException("getDefaulSchema",new Exception("Can't find default schema."));
58
                        }
59
                        schema = rs.getString("SCHEMA_NAME");
60
                        if (rs.next()){
61
                                throw new InitializeException("getDefaulSchema",new Exception("Checks catalog parm."));
62
                        }
63

    
64

    
65
                } catch (java.sql.SQLException e) {
66
                        // TODO Auto-generated catch block
67
                        throw new SQLException(sql,"getDefaultSchema",e);
68
                } finally{
69
                        try{
70
                                if (rs != null){
71
                                        rs.close();
72
                                } else if (st != null){
73
                                        st.close();
74
                                }
75
                        } catch (java.sql.SQLException e1){
76
                                //Ignore ??
77
                        }
78

    
79
                }
80
                return schema;
81

    
82
        }
83

    
84
        private static void loadFieldsToFeatureType(Connection conn,H2StoreParameters params,DBFeatureType featureType) throws ReadException{
85
                String sql="";
86
                String columns=params.getFieldsString();
87

    
88
                if (params.getSqlSoure() != null){
89
                        sql = params.getSqlSoure();
90
                } else {
91
                        sql = "Select "+columns+" from " + params.tableID() + " limit 1;";
92
                }
93

    
94
                try {
95

    
96
                        Statement stAux = conn.createStatement();
97
                        Statement stAux1 = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
98
                        ResultSet rs = stAux.executeQuery(sql);
99
                        ResultSetMetaData rsMetadata = rs.getMetaData();
100
                        String schemaFilter="";
101
                        if (params.getSchema() != null && params.getSchema() != ""){
102
                                schemaFilter = " TABLE_SCHEMA='" + params.getSchema() +"' AND ";
103
                        }
104
                        String sqlAllMeta = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS where "
105
                                + schemaFilter
106
                                + "TABLE_NAME='"+ params.getTableName() +"'";
107

    
108
                        ResultSet rsAllMeta = stAux1.executeQuery(sqlAllMeta);
109

    
110
//                        ResultSet rsAllMeta = conn.getMetaData().getAttributes(null, null, tableName, "*");
111

    
112
                        String colName;
113
                        int i;
114

    
115
                        featureType.setTableID(params.tableID());
116
                        DefaultAttributeDescriptor attr;
117
                        for (i=1;i<=rsMetadata.getColumnCount();i++){
118
                                colName= rsMetadata.getColumnName(i);
119
                                rsAllMeta.first();
120

    
121
                                while (true){
122
                                        if  (rsAllMeta.isAfterLast()){
123
                                                attr = getAttributeFromJDBC(conn,rsMetadata,i);
124
                                                featureType.add(attr);
125
                                                attr.setOrdinal(i-1);
126
                                                break;
127
                                        } else if(rsAllMeta.getString("COLUMN_NAME").equals(colName)){
128
                                                attr = getAttributeFromJDBC(conn,rsAllMeta);
129
                                                featureType.add(attr);
130
                                                attr.setOrdinal(i-1);
131
                                                break;
132
                                        }
133
                                        rsAllMeta.next();
134
                                }
135
                                if (attr.getName().equals(params.getGeometryField())){
136
                                        if (attr.getDataType().equals(IFeatureAttributeDescriptor.TYPE_OBJECT)){
137
                                                attr.setType(IFeatureAttributeDescriptor.TYPE_GEOMETRY);
138
                                        }else{
139
                                                throw new InitializeException(
140
                                                        "H2Utils.getFeatureType",
141
                                                        new Exception("Geometry Field '"
142
                                                                + params.getGeometryField()
143
                                                                + "' is a "
144
                                                                + attr.getDataType()
145
                                                                + " but sould be "
146
                                                                + IFeatureAttributeDescriptor.TYPE_OBJECT));
147
                                        }
148

    
149
                                }
150
                        }
151

    
152
                        rs.close();
153
                        rsAllMeta.close();
154
                } catch (java.sql.SQLException e) {
155
                        // TODO Auto-generated catch block
156
                        throw new SQLException(sql,"getFeatureType",e);
157
                }
158

    
159
        }
160

    
161
        static DBFeatureType getFeatureType(Connection conn,H2StoreParameters params) throws ReadException{
162
                DBFeatureType featureType = new DBFeatureType();
163

    
164

    
165
                loadFieldsToFeatureType(conn, params, featureType);
166

    
167

    
168
                featureType.setFieldsId(params.getFieldsId());
169

    
170
                if (params.getGeometryField() != null && params.getGeometryField() != ""){
171
                        if (featureType.getFieldIndex(params.getGeometryField())< 0){
172
                                // FIXME: crear una nueva excepcion??
173
                                throw new InitializeException(
174
                                                H2Store.DATASTORE_NAME,
175
                                                new Exception("Geometry Field '"+ params.getGeometryField() +"' not Found"));
176

    
177
                        }
178

    
179
                        featureType.setDefaultGeometry(params.getGeometryField());
180
                }
181

    
182
                return featureType;
183

    
184
        }
185

    
186
        private static DefaultAttributeDescriptor getAttributeFromJDBC(Connection conn,ResultSetMetaData rsMetadata,int colIndex) throws SQLException{
187
                JDBCAttributeDescriptor column= new JDBCAttributeDescriptor();
188
                try {
189
                        column.setName(rsMetadata.getColumnName(colIndex));
190
                        column.setSqlType(rsMetadata.getColumnType(colIndex));
191
                        switch (rsMetadata.getColumnType(colIndex)) {
192
                        case java.sql.Types.INTEGER:
193
                                column.setType(IFeatureAttributeDescriptor.TYPE_INT);
194
                                break;
195
                        case java.sql.Types.BIGINT:
196
                                column.setType(IFeatureAttributeDescriptor.TYPE_LONG);
197
                                break;
198
                        case java.sql.Types.REAL:
199
                                column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
200
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
201
                                break;
202
                        case java.sql.Types.DOUBLE:
203
                                column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
204
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
205
                                break;
206
                        case java.sql.Types.CHAR:
207
                                column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
208
                                column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
209
                                break;
210
                        case java.sql.Types.VARCHAR:
211
                                column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
212
                                column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
213
                                break;
214
                        case java.sql.Types.FLOAT:
215
                                column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
216
                                column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
217
                                break;
218
                        case java.sql.Types.DECIMAL:
219
                                column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
220
                                column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
221
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
222
                                break;
223
                        case java.sql.Types.DATE:
224
                                column.setType(IFeatureAttributeDescriptor.TYPE_DATE);
225
                                break;
226
                        case java.sql.Types.BOOLEAN:
227
                                column.setType(IFeatureAttributeDescriptor.TYPE_BOOLEAN);
228
                                break;
229
                        default:
230
                                column.setType(IFeatureAttributeDescriptor.TYPE_OBJECT);
231
                                break;
232
                        }
233
                } catch (java.sql.SQLException e){
234
                        throw new SQLException("","load attribute definition",e);
235
                }
236

    
237
                return column;
238

    
239
        }
240

    
241
        private static DefaultAttributeDescriptor getAttributeFromJDBC(Connection conn, ResultSet rsMetadata) throws SQLException{
242
                JDBCAttributeDescriptor column= new JDBCAttributeDescriptor();
243
                try {
244
                        column.setName(rsMetadata.getString("COLUMN_NAME"));
245
                        column.setSqlType(rsMetadata.getInt("DATA_TYPE"));
246
                        switch (rsMetadata.getInt("DATA_TYPE")) {
247
                        case java.sql.Types.INTEGER:
248
                                column.setType(IFeatureAttributeDescriptor.TYPE_INT);
249
                                break;
250
                        case java.sql.Types.BIGINT:
251
                                column.setType(IFeatureAttributeDescriptor.TYPE_LONG);
252
                                break;
253
                        case java.sql.Types.REAL:
254
                                column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
255
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
256
                                column.setPrecision(rsMetadata.getInt("NUMERIC_PRECISION"));
257
                                break;
258
                        case java.sql.Types.DOUBLE:
259
                                column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
260
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
261
                                column.setPrecision(rsMetadata.getInt("NUMERIC_PRECISION"));
262
                                break;
263
                        case java.sql.Types.CHAR:
264
                                column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
265
//                                column.setSize(rsMetadata.getInt("COLUMN_SIZE"));
266
                                column.setSize(rsMetadata.getInt("CHARACTER_MAXIMUM_LENGTH"));
267
                                break;
268
                        case java.sql.Types.VARCHAR:
269
                                column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
270
//                                column.setSize(rsMetadata.getInt("COLUMN_SIZE"));
271
                                column.setSize(rsMetadata.getInt("CHARACTER_MAXIMUM_LENGTH"));
272

    
273
                                break;
274
                        case java.sql.Types.FLOAT:
275
                                column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
276
//                                column.setSize(rsMetadata.getInt("COLUMN_SIZE"));
277
                                column.setSize(rsMetadata.getInt("CHARACTER_MAXIMUM_LENGTH"));
278
                                break;
279
                        case java.sql.Types.DECIMAL:
280
                                column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
281
//                                column.setSize(rsMetadata.getInt("COLUMN_SIZE"));
282
                                column.setSize(rsMetadata.getInt("CHARACTER_MAXIMUM_LENGTH"));
283
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
284
                                column.setPrecision(rsMetadata.getInt("NUMERIC_PRECISION"));
285
                                break;
286
                        case java.sql.Types.DATE:
287
                                column.setType(IFeatureAttributeDescriptor.TYPE_DATE);
288
                                break;
289
                        case java.sql.Types.BOOLEAN:
290
                                column.setType(IFeatureAttributeDescriptor.TYPE_BOOLEAN);
291
                                break;
292
                        default:
293
                                //FIXME: Falta comprobar si es geometrica!!!
294
                                column.setType(IFeatureAttributeDescriptor.TYPE_OBJECT);
295
                                break;
296
                        }
297

    
298
                        column.setDefaultValue(rsMetadata.getObject("COLUMN_DEFAULT"));
299
                        column.setAllowNull(rsMetadata.getBoolean("IS_NULLABLE"));
300
                } catch (java.sql.SQLException e){
301
                        throw new SQLException("","load attribute definition",e);
302
                }
303

    
304
                return column;
305

    
306
        }
307

    
308

    
309

    
310
        static void initializeTableEPSG_and_shapeType(Connection conn,String tableID, DBFeatureType dbld) throws ReadException {
311
                try {
312
                        Statement stAux = conn.createStatement();
313

    
314
//                        String sql = "SELECT * FROM GEOMETRY_COLUMNS WHERE F_TABLE_NAME = '"
315
//                                        + getTableName() + "' AND F_GEOMETRY_COLUMN = '" + getLyrDef().getFieldGeometry() + "'";
316
                        String sql= "SELECT SRID("+dbld.getDefaultGeometry()+"), GeometryType("+dbld.getDefaultGeometry()+") FROM "+tableID +" WHERE "+dbld.getDefaultGeometry()+" is not null LIMIT 1";
317

    
318
                        ResultSet rs = stAux.executeQuery(sql);
319
                        if(!rs.next()){
320
                                dbld.setDefaultSRS("");
321
                                dbld.setGeometryTypes(new int[]{FShape.MULTI});
322
                                return;
323
                        }
324
                        dbld.setDefaultSRS("EPSG:"+rs.getInt(1));
325

    
326
                        String geometryType = rs.getString(2);
327
                        int shapeType = FShape.MULTI;
328
                        if (geometryType.compareToIgnoreCase("Point") == 0)
329
                                shapeType = FShape.POINT;
330
                        else if (geometryType.compareToIgnoreCase("LineString") == 0)
331
                                shapeType = FShape.LINE;
332
                        else if (geometryType.compareToIgnoreCase("Polygon") == 0)
333
                                shapeType = FShape.POLYGON;
334
                        else if (geometryType.compareToIgnoreCase("MultiPoint") == 0)
335
                                shapeType = FShape.POINT;
336
                        else if (geometryType.compareToIgnoreCase("MultiLineString") == 0)
337
                                shapeType = FShape.LINE;
338
                        else if (geometryType.compareToIgnoreCase("MultiPolygon") == 0)
339
                                shapeType = FShape.POLYGON;
340

    
341
                        dbld.setGeometryTypes(new int[]{shapeType});
342
                        rs.close();
343

    
344
                } catch (java.sql.SQLException e) {
345
                        dbld.setDefaultSRS("");
346
                        dbld.setGeometryTypes(new int[]{FShape.MULTI});
347
                        throw new ReadException("H2Utils.getTableEPSG_and_shapeType",e);
348
                }
349

    
350
        }
351

    
352
        static String getConnectionResourceID(String dbUrl,String dbUser){
353
                return H2Store.CONNECTION_STRING+";"+dbUrl+";"+dbUser;
354

    
355
        }
356

    
357

    
358
        static String getJDBCUrl(String host,String db){
359
                String url;
360
                url = "jdbc:h2:tcp://"+host;
361
                if (db == null || db == ""){
362
                        url=url+"/default";
363
                }else {
364
                        url=url+"/"+db;
365
                }
366

    
367
                return url;
368
        }
369

    
370
        static Connection getConnection(String dbUrl,String dbUser, String dbPass) throws InitializeException{
371
                //TODO: Aqu? habria que implementar la llamada
372
                //      al Resource Manager para comprobar si ya hay
373
                //                una connexion a la BD
374
                String connID = getConnectionResourceID(dbUrl, dbUser);
375

    
376
                Connection conn = null;
377
//                IResource res = ResourceManager.getResourceManager().getResource(connID);
378

    
379

    
380

    
381
                try {
382
                        Class.forName("org.h2.Driver");
383
                } catch (ClassNotFoundException e) {
384
                        throw new JDBCDriverNotFoundException("org.h2.Driver",e);
385
                }
386
                try {
387
                        conn = DriverManager.getConnection(dbUrl, dbUser, dbPass);
388
                        conn.setAutoCommit(false);
389

    
390
                } catch (java.sql.SQLException e1) {
391
                        throw new InitializeException("H2",e1);
392
                }
393
                //TODO: Registrar en el Resource manager
394
                // ResourceManager.getResourceManager().addResource(res);
395

    
396
                return conn;
397
        }
398

    
399
        static Object[] getPkFromResulset(ResultSet rs, DBFeatureType featureType) throws java.sql.SQLException{
400
                String[] fieldsId = featureType.getFieldsId();
401
                Object[] result = new Object[fieldsId.length];
402
                for (int i=0;i<fieldsId.length;i++){
403
                        result[i] = rs.getObject(fieldsId[i]);
404
                }
405
                return result;
406

    
407
        }
408

    
409
        static Object[] getPkFromFeature(IFeature feature, DBFeatureType featureType){
410
                String[] fieldsId = featureType.getFieldsId();
411
                Object[] result = new Object[fieldsId.length];
412
                for (int i=0;i<fieldsId.length;i++){
413
                        result[i] = feature.get(fieldsId[i]);
414
                }
415
                return result;
416

    
417
        }
418

    
419
        static IFeature createFeature(JDBCStore store,ResultSet rs,IFeatureType featureType) throws ReadException{
420

    
421
                JDBCFeature feature=null;
422

    
423
                if (featureType == null){
424
                        featureType = store.getDefaultFeatureType();
425
                }
426

    
427

    
428
                Object[] pk;
429
                try {
430
                        pk = getPkFromResulset(rs, (DBFeatureType) store.getDefaultFeatureType());
431

    
432
                        feature=new H2Feature(featureType,store,pk);
433

    
434
                        Iterator iter = featureType.iterator();
435
                        IGeometry geom = null;
436
                        while (iter.hasNext()) {
437
                                IFeatureAttributeDescriptor fad=(IFeatureAttributeDescriptor)iter.next();
438
                                if (fad.getDataType().equals(IFeatureAttributeDescriptor.TYPE_GEOMETRY)) {
439
                                        byte[] data = rs.getBytes(fad.getName());
440

    
441
                                        if (data == null) {
442
                                                geom = null;
443
                                        } else{
444
                                                geom = wkbParser.parse(data);
445
                                        }
446
//                                        feature.setDefaultGeometry(geom);
447
                                        feature.setGeometry(fad.getName(),geom);
448
                                } else {
449
                                        feature.set(fad.getName(), rs.getObject(fad.getName()));
450
                                }
451

    
452
                        }
453
                        return feature;
454
                } catch (java.sql.SQLException e) {
455
                        throw new ReadException("CreateFeature",e);
456
                }
457
        }
458

    
459
        static String objectToSqlString(Object obj){
460
                if (obj instanceof String){
461
                        return "'"+ scapeString((String)obj) +"'";
462
                } else if (obj == null){
463
                        return "null";
464
                }else{
465
                        // OJO con otros tipos!!
466
                        return obj.toString();
467
                }
468

    
469
        }
470

    
471
        static String scapeString(String str){
472
                return str.replace("'", "''");
473
        }
474

    
475
}