Statistics
| Revision:

root / trunk / libraries / libDataSourceDBBaseDrivers / src / org / gvsig / data / datastores / vectorial / driver / jdbc / h2 / H2Utils.java @ 19802

History | View | Annotate | Download (15.3 KB)

1
package org.gvsig.data.datastores.vectorial.driver.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.driver.jdbc.DBAttributeDescriptor;
12
import org.gvsig.data.datastores.vectorial.driver.jdbc.DBFeatureType;
13
import org.gvsig.data.datastores.vectorial.driver.jdbc.exception.JDBCDriverNotFoundException;
14
import org.gvsig.data.datastores.vectorial.driver.jdbc.exception.SQLException;
15
import org.gvsig.data.exception.InitializeException;
16
import org.gvsig.data.exception.ReadException;
17
import org.gvsig.data.vectorial.DefaultAttributeDescriptor;
18
import org.gvsig.data.vectorial.IFeature;
19
import org.gvsig.data.vectorial.IFeatureAttributeDescriptor;
20

    
21
import com.iver.cit.gvsig.fmap.core.FShape;
22
import com.iver.cit.gvsig.fmap.core.IGeometry;
23
import com.iver.cit.gvsig.fmap.drivers.WKBParser2;
24
import com.vividsolutions.jts.io.WKBWriter;
25

    
26
public class H2Utils {
27
        private static WKBParser2 wkbParser = new WKBParser2();
28
        private static WKBWriter wkbWriter = new WKBWriter();
29

    
30
        static String getFliterForID(DBFeatureType fType, IFeature feature){
31
                return getFliterForID(fType, getPkFromFeature(feature,fType));
32
        }
33

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

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

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

    
62

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

    
77
                }
78
                return schema;
79

    
80
        }
81

    
82
        static DBFeatureType getFeatureType(Connection conn,H2StoreParameters params) throws ReadException{
83
                String sql="";
84
                String columns=params.getFieldsString();
85

    
86
                if (columns == null || columns == ""){
87
                        columns = "*";
88
                }
89

    
90

    
91
                try {
92
                        sql = "Select "+columns+" from " + params.tableID() + " limit 1;";
93
                        Statement stAux = conn.createStatement();
94
                        Statement stAux1 = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
95
                        ResultSet rs = stAux.executeQuery(sql);
96
                        ResultSetMetaData rsMetadata = rs.getMetaData();
97
                        String schemaFilter="";
98
                        if (params.getSchema() != null && params.getSchema() != ""){
99
                                schemaFilter = " TABLE_SCHEMA='" + params.getSchema() +"' AND ";
100
                        }
101
                        String sqlAllMeta = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS where "
102
                                + schemaFilter
103
                                + "TABLE_NAME='"+ params.getTableName() +"'";
104

    
105
                        ResultSet rsAllMeta = stAux1.executeQuery(sqlAllMeta);
106

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

    
109
                        String colName;
110
                        int i;
111
                        DBFeatureType featureType = new DBFeatureType();
112
                        featureType.setTableID(params.tableID());
113
                        DefaultAttributeDescriptor attr;
114
                        for (i=1;i<=rsMetadata.getColumnCount();i++){
115
                                colName= rsMetadata.getColumnName(i);
116
                                rsAllMeta.first();
117

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

    
146
                                }
147
                        }
148

    
149
                        rs.close();
150
                        rsAllMeta.close();
151

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

    
158
        }
159

    
160
        private static DefaultAttributeDescriptor getAttributeFromJDBC(Connection conn,ResultSetMetaData rsMetadata,int colIndex) throws SQLException{
161
                DBAttributeDescriptor column= new DBAttributeDescriptor();
162
                try {
163
                        column.setName(rsMetadata.getColumnName(colIndex));
164
                        column.setSqlType(rsMetadata.getColumnType(colIndex));
165
                        switch (rsMetadata.getColumnType(colIndex)) {
166
                        case java.sql.Types.INTEGER:
167
                                column.setType(IFeatureAttributeDescriptor.TYPE_INT);
168
                                break;
169
                        case java.sql.Types.BIGINT:
170
                                column.setType(IFeatureAttributeDescriptor.TYPE_LONG);
171
                                break;
172
                        case java.sql.Types.REAL:
173
                                column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
174
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
175
                                break;
176
                        case java.sql.Types.DOUBLE:
177
                                column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
178
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
179
                                break;
180
                        case java.sql.Types.CHAR:
181
                                column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
182
                                column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
183
                                break;
184
                        case java.sql.Types.VARCHAR:
185
                                column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
186
                                column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
187
                                break;
188
                        case java.sql.Types.FLOAT:
189
                                column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
190
                                column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
191
                                break;
192
                        case java.sql.Types.DECIMAL:
193
                                column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
194
                                column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
195
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
196
                                break;
197
                        case java.sql.Types.DATE:
198
                                column.setType(IFeatureAttributeDescriptor.TYPE_DATE);
199
                                break;
200
                        case java.sql.Types.BOOLEAN:
201
                                column.setType(IFeatureAttributeDescriptor.TYPE_BOOLEAN);
202
                                break;
203
                        default:
204
                                column.setType(IFeatureAttributeDescriptor.TYPE_OBJECT);
205
                                break;
206
                        }
207
                } catch (java.sql.SQLException e){
208
                        throw new SQLException("","load attribute definition",e);
209
                }
210

    
211
                return column;
212

    
213
        }
214

    
215
        private static DefaultAttributeDescriptor getAttributeFromJDBC(Connection conn, ResultSet rsMetadata) throws SQLException{
216
                DBAttributeDescriptor column= new DBAttributeDescriptor();
217
                try {
218
                        column.setName(rsMetadata.getString("COLUMN_NAME"));
219
                        column.setSqlType(rsMetadata.getInt("DATA_TYPE"));
220
                        switch (rsMetadata.getInt("DATA_TYPE")) {
221
                        case java.sql.Types.INTEGER:
222
                                column.setType(IFeatureAttributeDescriptor.TYPE_INT);
223
                                break;
224
                        case java.sql.Types.BIGINT:
225
                                column.setType(IFeatureAttributeDescriptor.TYPE_LONG);
226
                                break;
227
                        case java.sql.Types.REAL:
228
                                column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
229
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
230
                                column.setPrecision(rsMetadata.getInt("NUMERIC_PRECISION"));
231
                                break;
232
                        case java.sql.Types.DOUBLE:
233
                                column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
234
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
235
                                column.setPrecision(rsMetadata.getInt("NUMERIC_PRECISION"));
236
                                break;
237
                        case java.sql.Types.CHAR:
238
                                column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
239
//                                column.setSize(rsMetadata.getInt("COLUMN_SIZE"));
240
                                column.setSize(rsMetadata.getInt("CHARACTER_MAXIMUM_LENGTH"));
241
                                break;
242
                        case java.sql.Types.VARCHAR:
243
                                column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
244
//                                column.setSize(rsMetadata.getInt("COLUMN_SIZE"));
245
                                column.setSize(rsMetadata.getInt("CHARACTER_MAXIMUM_LENGTH"));
246

    
247
                                break;
248
                        case java.sql.Types.FLOAT:
249
                                column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
250
//                                column.setSize(rsMetadata.getInt("COLUMN_SIZE"));
251
                                column.setSize(rsMetadata.getInt("CHARACTER_MAXIMUM_LENGTH"));
252
                                break;
253
                        case java.sql.Types.DECIMAL:
254
                                column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
255
//                                column.setSize(rsMetadata.getInt("COLUMN_SIZE"));
256
                                column.setSize(rsMetadata.getInt("CHARACTER_MAXIMUM_LENGTH"));
257
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
258
                                column.setPrecision(rsMetadata.getInt("NUMERIC_PRECISION"));
259
                                break;
260
                        case java.sql.Types.DATE:
261
                                column.setType(IFeatureAttributeDescriptor.TYPE_DATE);
262
                                break;
263
                        case java.sql.Types.BOOLEAN:
264
                                column.setType(IFeatureAttributeDescriptor.TYPE_BOOLEAN);
265
                                break;
266
                        default:
267
                                //FIXME: Falta comprobar si es geometrica!!!
268
                                column.setType(IFeatureAttributeDescriptor.TYPE_OBJECT);
269
                                break;
270
                        }
271

    
272
                        column.setDefaultValue(rsMetadata.getObject("COLUMN_DEFAULT"));
273
                        column.setAllowNull(rsMetadata.getBoolean("IS_NULLABLE"));
274
                } catch (java.sql.SQLException e){
275
                        throw new SQLException("","load attribute definition",e);
276
                }
277

    
278
                return column;
279

    
280
        }
281

    
282

    
283

    
284
        static void initializeTableEPSG_and_shapeType(Connection conn,String tableID, DBFeatureType dbld) throws ReadException {
285
                try {
286
                        Statement stAux = conn.createStatement();
287

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

    
292
                        ResultSet rs = stAux.executeQuery(sql);
293
                        if(!rs.next()){
294
                                dbld.setDefaultSRS("");
295
                                dbld.setGeometryTypes(new int[]{FShape.MULTI});
296
                                return;
297
                        }
298
                        dbld.setDefaultSRS("EPSG:"+rs.getInt(1));
299

    
300
                        String geometryType = rs.getString(2);
301
                        int shapeType = FShape.MULTI;
302
                        if (geometryType.compareToIgnoreCase("Point") == 0)
303
                                shapeType = FShape.POINT;
304
                        else if (geometryType.compareToIgnoreCase("LineString") == 0)
305
                                shapeType = FShape.LINE;
306
                        else if (geometryType.compareToIgnoreCase("Polygon") == 0)
307
                                shapeType = FShape.POLYGON;
308
                        else if (geometryType.compareToIgnoreCase("MultiPoint") == 0)
309
                                shapeType = FShape.POINT;
310
                        else if (geometryType.compareToIgnoreCase("MultiLineString") == 0)
311
                                shapeType = FShape.LINE;
312
                        else if (geometryType.compareToIgnoreCase("MultiPolygon") == 0)
313
                                shapeType = FShape.POLYGON;
314

    
315
                        dbld.setGeometryTypes(new int[]{shapeType});
316
                        rs.close();
317

    
318
                } catch (java.sql.SQLException e) {
319
                        dbld.setDefaultSRS("");
320
                        dbld.setGeometryTypes(new int[]{FShape.MULTI});
321
                        throw new ReadException("H2DriverUtils.getTableEPSG_and_shapeType",e);
322
                }
323

    
324
        }
325

    
326
        static String getConnectionResourceID(String dbUrl,String dbUser){
327
                return H2Store.CONNECTION_STRING+";"+dbUrl+";"+dbUser;
328

    
329
        }
330

    
331

    
332
        static String getJDBCUrl(String host,String db){
333
                String url;
334
                url = "jdbc:h2:tcp://"+host;
335
                if (db == null || db == ""){
336
                        url=url+"/default";
337
                }else {
338
                        url=url+"/"+db;
339
                }
340

    
341
                return url;
342
        }
343

    
344
        static Connection getConnection(String dbUrl,String dbUser, String dbPass) throws InitializeException{
345
                //TODO: Aqu? habria que implementar la llamada
346
                //      al Resource Manager para comprobar si ya hay
347
                //                una connexion a la BD
348
                String connID = getConnectionResourceID(dbUrl, dbUser);
349

    
350
                Connection conn = null;
351
//                IResource res = ResourceManager.getResourceManager().getResource(connID);
352

    
353

    
354

    
355
                try {
356
                        Class.forName("org.h2.Driver");
357
                } catch (ClassNotFoundException e) {
358
                        throw new JDBCDriverNotFoundException("org.h2.Driver",e);
359
                }
360
                try {
361
                        conn = DriverManager.getConnection(dbUrl, dbUser, dbPass);
362
                        conn.setAutoCommit(false);
363

    
364
                } catch (java.sql.SQLException e1) {
365
                        throw new InitializeException("H2",e1);
366
                }
367
                //TODO: Registrar en el Resource manager
368
                // ResourceManager.getResourceManager().addResource(res);
369

    
370
                return conn;
371
        }
372

    
373
        static Object[] getPkFromResulset(ResultSet rs, DBFeatureType featureType) throws java.sql.SQLException{
374
                String[] fieldsId = featureType.getFieldsId();
375
                Object[] result = new Object[fieldsId.length];
376
                for (int i=0;i<fieldsId.length;i++){
377
                        result[i] = rs.getObject(fieldsId[i]);
378
                }
379
                return result;
380

    
381
        }
382

    
383
        static Object[] getPkFromFeature(IFeature feature, DBFeatureType featureType){
384
                String[] fieldsId = featureType.getFieldsId();
385
                Object[] result = new Object[fieldsId.length];
386
                for (int i=0;i<fieldsId.length;i++){
387
                        result[i] = feature.get(fieldsId[i]);
388
                }
389
                return result;
390

    
391
        }
392

    
393
        static IFeature createFeature(H2Store driver,ResultSet rs,DBFeatureType featureType) throws ReadException{
394

    
395
                H2Feature feature=null;
396

    
397

    
398
                Object[] pk;
399
                try {
400
                        pk = getPkFromResulset(rs, featureType);
401

    
402
                        feature=new H2Feature(featureType,driver,pk);
403

    
404
                        Iterator iter = featureType.iterator();
405
                        IGeometry geom = null;
406
                        while (iter.hasNext()) {
407
                                IFeatureAttributeDescriptor fad=(IFeatureAttributeDescriptor)iter.next();
408
                                if (fad.getDataType().equals(IFeatureAttributeDescriptor.TYPE_GEOMETRY)) {
409
                                        byte[] data = rs.getBytes(fad.getName());
410

    
411
                                        if (data == null) {
412
                                                geom = null;
413
                                        } else{
414
                                                geom = wkbParser.parse(data);
415
                                        }
416
//                                        feature.setDefaultGeometry(geom);
417
                                        feature.set(fad.getName(),geom);
418
                                } else {
419
                                        feature.set(fad.getName(), rs.getObject(fad.getName()));
420
                                }
421

    
422
                        }
423
                        return feature;
424
                } catch (java.sql.SQLException e) {
425
                        throw new ReadException("CreateFeature",e);
426
                }
427
        }
428

    
429
        static String objectToSqlString(Object obj){
430
                if (obj instanceof String){
431
                        return "'"+ scapeString((String)obj) +"'";
432
                } else if (obj == null){
433
                        return "null";
434
                }else{
435
                        // OJO con otros tipos!!
436
                        return obj.toString();
437
                }
438

    
439
        }
440

    
441
        static String scapeString(String str){
442
                return str.replace("'", "''");
443
        }
444

    
445
        static void loadPkInPreparedStatement(PreparedStatement ps,int paramIndex,DBFeatureType fType,IFeature feature) throws java.sql.SQLException{
446
                if (fType.getFieldsId().length != 1)
447
                        throw new UnsupportedOperationException("ID fields > 1");
448
                String id =fType.getFieldsId()[0];
449
                loadValueInPreparedStatement(ps, paramIndex, (DBAttributeDescriptor)fType.get(fType.getFieldIndex(id)), feature);
450
        }
451

    
452
        static void loadValueInPreparedStatement(PreparedStatement ps,int paramIndex,DBAttributeDescriptor attr,IFeature feature) throws java.sql.SQLException{
453
                Object value = feature.get(attr.ordinal());
454
                if (value == null){
455
                        ps.setNull(paramIndex, attr.getSqlType());
456
                        return;
457
                }
458

    
459
                if (attr.getDataType() == IFeatureAttributeDescriptor.TYPE_GEOMETRY){
460
                        IGeometry geom =(IGeometry)feature.get(attr.ordinal());
461
                        ps.setBytes(
462
                                paramIndex,        wkbWriter.write(geom.toJTSGeometry())
463
                        );
464
                        return;
465
                }
466
                ps.setObject(paramIndex, feature.get(attr.ordinal()));
467
        }
468

    
469
        public static String getFliterForIDForPStatement(DBFeatureType fType) {
470
                if (fType.getFieldsId().length != 1)
471
                        throw new UnsupportedOperationException("ID fields > 1");
472
                String id =fType.getFieldsId()[0];
473
                return id + " = ?";
474
        }
475
}