Statistics
| Revision:

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

History | View | Annotate | Download (15.1 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.ArrayList;
10
import java.util.Iterator;
11

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

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

    
30
public class H2Utils {
31

    
32

    
33

    
34
        static String getDefaultSchema(Connection conn, String catalog) throws InitializeException {
35
                String sql= "SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE IS_DEFAULT = TRUE";
36
                if (catalog != null && catalog !=""){
37
                        sql= sql+ " AND CATALOG_NAME = '"+catalog+"'";
38
                }
39

    
40
                String schema = null;
41
                Statement st = null;
42
                ResultSet rs= null;
43
                try{
44
                        st = conn.createStatement(ResultSet.FETCH_FORWARD, ResultSet.CONCUR_READ_ONLY);
45
                        rs = st.executeQuery(sql);
46
                        if (!rs.next()){
47
                                throw new InitializeException("getDefaulSchema",new Exception("Can't find default schema."));
48
                        }
49
                        schema = rs.getString("SCHEMA_NAME");
50
                        if (rs.next()){
51
                                throw new InitializeException("getDefaulSchema",new Exception("Checks catalog parm."));
52
                        }
53

    
54

    
55
                } catch (java.sql.SQLException e) {
56
                        // TODO Auto-generated catch block
57
                        throw new SQLException(sql,"getDefaultSchema",e);
58
                } finally{
59
                        try{
60
                                if (rs != null){
61
                                        rs.close();
62
                                } else if (st != null){
63
                                        st.close();
64
                                }
65
                        } catch (java.sql.SQLException e1){
66
                                //Ignore ??
67
                        }
68

    
69
                }
70
                return schema;
71
        }
72

    
73
        private static void loadFieldsToFeatureType(Connection conn,H2StoreParameters params,DBFeatureType featureType) throws ReadException{
74
                String sql="";
75
                String columns=params.getFieldsString();
76

    
77
                if (params.getSqlSoure() != null){
78
                        sql = params.getSqlSoure();
79
                } else {
80
                        sql = "Select "+columns+" from " + params.tableID() + " limit 1;";
81
                }
82

    
83
                try {
84

    
85
                        Statement stAux = conn.createStatement();
86
                        Statement stAux1 = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
87
                        ResultSet rs = stAux.executeQuery(sql);
88
                        ResultSetMetaData rsMetadata = rs.getMetaData();
89
                        String schemaFilter="";
90
                        if (params.getSchema() != null && params.getSchema() != ""){
91
                                schemaFilter = " TABLE_SCHEMA='" + params.getSchema() +"' AND ";
92
                        }
93
                        String sqlAllMeta = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS where "
94
                                + schemaFilter
95
                                + "TABLE_NAME='"+ params.getTableName() +"'";
96

    
97
                        ResultSet rsAllMeta = stAux1.executeQuery(sqlAllMeta);
98

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

    
101
                        String colName;
102
                        int i;
103

    
104
                        featureType.setTableID(params.tableID());
105
                        DefaultAttributeDescriptor attr;
106
                        for (i=1;i<=rsMetadata.getColumnCount();i++){
107
                                colName= rsMetadata.getColumnName(i);
108
                                rsAllMeta.first();
109

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

    
138
                                }
139
                        }
140

    
141
                        rs.close();
142
                        rsAllMeta.close();
143
                } catch (java.sql.SQLException e) {
144
                        // TODO Auto-generated catch block
145
                        throw new SQLException(sql,"getFeatureType",e);
146
                }
147

    
148
        }
149

    
150
        static DBFeatureType getFeatureType(Connection conn,H2StoreParameters params) throws ReadException{
151
                DBFeatureType featureType = new DBFeatureType();
152

    
153

    
154
                loadFieldsToFeatureType(conn, params, featureType);
155

    
156

    
157
                if (params.getFieldsId() == null || params.getFieldsId().length == 0){
158
                        featureType.setFieldsId(loadFieldsId(conn,params));
159
                } else{
160
                        featureType.setFieldsId(params.getFieldsId());
161
                }
162

    
163
                if (params.getGeometryField() != null && params.getGeometryField() != ""){
164
                        if (featureType.getFieldIndex(params.getGeometryField())< 0){
165
                                // FIXME: crear una nueva excepcion??
166
                                throw new InitializeException(
167
                                                H2Store.DATASTORE_NAME,
168
                                                new Exception("Geometry Field '"+ params.getGeometryField() +"' not Found"));
169

    
170
                        }
171

    
172
                        featureType.setDefaultGeometry(params.getGeometryField());
173
                }
174

    
175
                return featureType;
176

    
177
        }
178

    
179
        private static String[] loadFieldsId(Connection conn, H2StoreParameters params) throws ReadException {
180
                Statement st;
181
                StringBuffer sql = new StringBuffer();
182
                ResultSet rs;
183
                ArrayList list = new ArrayList();
184
                /*SELECT column_name FROM INFORMATION_SCHEMA.INDEXES
185
                 *   WHERE table_name='' AND
186
                 *         table_schema='' AND
187
                 *         table_catalog=''
188
                 *         AND index_type_name='PRIMARY KEY'
189
                 *
190
                 */
191
                sql.append("SELECT column_name FROM INFORMATION_SCHEMA.INDEXES WHERE table_name like '");
192
                sql.append(params.getTableName());
193
                sql.append("' AND table_schema like '");
194

    
195
                if (params.getSchema() == null || params.getSchema() == ""){
196
                        sql.append(getDefaultSchema(conn, params.getDb()));
197
                } else{
198
                        sql.append(params.getSchema());
199
                }
200

    
201

    
202
                if (params.getCatalog() == null || params.getCatalog() == ""){
203
                        if (params.getDb() != null && params.getDb() != ""){
204
                                sql.append("' AND table_catalog like '");
205
                                sql.append(params.getDb());
206
                        }
207
                } else {
208
                        sql.append("' AND table_catalog like '");
209
                        sql.append(params.getCatalog());
210
                }
211

    
212

    
213

    
214
                sql.append("' AND index_type_name='PRIMARY KEY'");
215

    
216
                try {
217
                        st = conn.createStatement();
218
                        rs = st.executeQuery(sql.toString());
219
                        while (rs.next()){
220
                                list.add(rs.getString(1));
221
                        }
222
                        rs.close();
223
                        st.close();
224

    
225
                } catch (java.sql.SQLException e) {
226
                        throw new ReadException(params.getDataStoreName(),e);
227
                }
228

    
229
                String[] x = new String[] {""};
230
                return (String[])list.toArray(x);
231

    
232
        }
233

    
234
        private static DefaultAttributeDescriptor getAttributeFromJDBC(Connection conn,ResultSetMetaData rsMetadata,int colIndex) throws SQLException{
235
                JDBCAttributeDescriptor column= new JDBCAttributeDescriptor();
236
                try {
237
                        column.setName(rsMetadata.getColumnName(colIndex));
238
                        column.setCaseSensitive(rsMetadata.isCaseSensitive(colIndex));
239
                        column.setSqlType(rsMetadata.getColumnType(colIndex));
240
                        column.setAllowNull(rsMetadata.isNullable(colIndex) == ResultSetMetaData.columnNullable);
241
                        column.setAutoIncrement(rsMetadata.isAutoIncrement(colIndex));
242
                        column.setReadOnly(rsMetadata.isReadOnly(colIndex));
243
                        column.setWritable(rsMetadata.isWritable(colIndex));
244
                        column.setClassName(rsMetadata.getColumnClassName(colIndex));
245
                        column.setCatalogName(rsMetadata.getCatalogName(colIndex));
246
                        column.setDefinitelyWritable(rsMetadata.isDefinitelyWritable(colIndex));
247
                        column.setLabel(rsMetadata.getColumnLabel(colIndex));
248
                        column.setSchemaName(rsMetadata.getSchemaName(colIndex));
249
                        column.setTableName(rsMetadata.getTableName(colIndex));
250
                        column.setCatalogName(rsMetadata.getCatalogName(colIndex));
251
                        column.setSqlTypeName(rsMetadata.getColumnTypeName(colIndex));
252
                        column.setSearchable(rsMetadata.isSearchable(colIndex));
253
                        column.setSigned(rsMetadata.isSigned(colIndex));
254
                        column.setCurrency(rsMetadata.isCurrency(colIndex));
255
                        column.setPrecision(rsMetadata.getPrecision(colIndex));
256
                        column.setSize(rsMetadata.getColumnDisplaySize(colIndex));                        switch (rsMetadata.getColumnType(colIndex)) {
257
                        case java.sql.Types.INTEGER:
258
                                column.setType(IFeatureAttributeDescriptor.TYPE_INT);
259
                                break;
260
                        case java.sql.Types.BIGINT:
261
                                column.setType(IFeatureAttributeDescriptor.TYPE_LONG);
262
                                break;
263
                        case java.sql.Types.REAL:
264
                                column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
265
                                break;
266
                        case java.sql.Types.DOUBLE:
267
                                column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
268
                                break;
269
                        case java.sql.Types.CHAR:
270
                                column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
271
                                break;
272
                        case java.sql.Types.VARCHAR:
273
                                column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
274
                                break;
275
                        case java.sql.Types.FLOAT:
276
                                column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
277
                                break;
278
                        case java.sql.Types.DECIMAL:
279
                                column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
280
                                break;
281
                        case java.sql.Types.DATE:
282
                                column.setType(IFeatureAttributeDescriptor.TYPE_DATE);
283
                                break;
284
                        case java.sql.Types.TIME:
285
                                column.setType(IFeatureAttributeDescriptor.TYPE_TIME);
286
                                break;
287
                        case java.sql.Types.TIMESTAMP:
288
                                column.setType(IFeatureAttributeDescriptor.TYPE_TIMESTAMP);
289
                                break;
290
                        case java.sql.Types.BOOLEAN:
291
                                column.setType(IFeatureAttributeDescriptor.TYPE_BOOLEAN);
292
                                break;
293
                        default:
294
                                column.setType(IFeatureAttributeDescriptor.TYPE_OBJECT);
295
                                break;
296
                        }
297
                } catch (java.sql.SQLException e){
298
                        throw new SQLException("","load attribute definition",e);
299
                }
300

    
301
                return column;
302

    
303
        }
304

    
305
        private static DefaultAttributeDescriptor getAttributeFromJDBC(Connection conn, ResultSet rsMetadata) throws SQLException{
306
                JDBCAttributeDescriptor column= new JDBCAttributeDescriptor();
307
                try {
308
                        column.setName(rsMetadata.getString("COLUMN_NAME"));
309
                        column.setSqlType(rsMetadata.getInt("DATA_TYPE"));
310
                        switch (rsMetadata.getInt("DATA_TYPE")) {
311
                        case java.sql.Types.INTEGER:
312
                                column.setType(IFeatureAttributeDescriptor.TYPE_INT);
313
                                break;
314
                        case java.sql.Types.BIGINT:
315
                                column.setType(IFeatureAttributeDescriptor.TYPE_LONG);
316
                                break;
317
                        case java.sql.Types.REAL:
318
                                column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
319
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
320
                                column.setPrecision(rsMetadata.getInt("NUMERIC_PRECISION"));
321
                                break;
322
                        case java.sql.Types.DOUBLE:
323
                                column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
324
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
325
                                column.setPrecision(rsMetadata.getInt("NUMERIC_PRECISION"));
326
                                break;
327
                        case java.sql.Types.CHAR:
328
                                column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
329
//                                column.setSize(rsMetadata.getInt("COLUMN_SIZE"));
330
                                column.setSize(rsMetadata.getInt("CHARACTER_MAXIMUM_LENGTH"));
331
                                break;
332
                        case java.sql.Types.VARCHAR:
333
                                column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
334
//                                column.setSize(rsMetadata.getInt("COLUMN_SIZE"));
335
                                column.setSize(rsMetadata.getInt("CHARACTER_MAXIMUM_LENGTH"));
336

    
337
                                break;
338
                        case java.sql.Types.FLOAT:
339
                                column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
340
//                                column.setSize(rsMetadata.getInt("COLUMN_SIZE"));
341
                                column.setSize(rsMetadata.getInt("CHARACTER_MAXIMUM_LENGTH"));
342
                                break;
343
                        case java.sql.Types.DECIMAL:
344
                                column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
345
//                                column.setSize(rsMetadata.getInt("COLUMN_SIZE"));
346
                                column.setSize(rsMetadata.getInt("CHARACTER_MAXIMUM_LENGTH"));
347
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
348
                                column.setPrecision(rsMetadata.getInt("NUMERIC_PRECISION"));
349
                                break;
350
                        case java.sql.Types.DATE:
351
                                column.setType(IFeatureAttributeDescriptor.TYPE_DATE);
352
                                break;
353
                        case java.sql.Types.BOOLEAN:
354
                                column.setType(IFeatureAttributeDescriptor.TYPE_BOOLEAN);
355
                                break;
356
                        default:
357
                                //FIXME: Falta comprobar si es geometrica!!!
358
                                column.setType(IFeatureAttributeDescriptor.TYPE_OBJECT);
359
                                break;
360
                        }
361

    
362
                        column.setDefaultValue(rsMetadata.getObject("COLUMN_DEFAULT"));
363
                        column.setAllowNull(rsMetadata.getBoolean("IS_NULLABLE"));
364
                } catch (java.sql.SQLException e){
365
                        throw new SQLException("","load attribute definition",e);
366
                }
367

    
368
                return column;
369

    
370
        }
371

    
372

    
373

    
374
        static void initializeTableEPSG_and_shapeType(Connection conn,String tableID, DBFeatureType dbld) throws ReadException {
375
                try {
376
                        Statement stAux = conn.createStatement();
377

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

    
382
                        ResultSet rs = stAux.executeQuery(sql);
383
                        if(!rs.next()){
384
                                dbld.setDefaultSRS("");
385
                                dbld.setGeometryTypes(new int[]{FShape.MULTI});
386
                                return;
387
                        }
388
                        dbld.setDefaultSRS("EPSG:"+rs.getInt(1));
389

    
390
                        String geometryType = rs.getString(2);
391
                        int shapeType = FShape.MULTI;
392
                        if (geometryType.compareToIgnoreCase("Point") == 0)
393
                                shapeType = FShape.POINT;
394
                        else if (geometryType.compareToIgnoreCase("LineString") == 0)
395
                                shapeType = FShape.LINE;
396
                        else if (geometryType.compareToIgnoreCase("Polygon") == 0)
397
                                shapeType = FShape.POLYGON;
398
                        else if (geometryType.compareToIgnoreCase("MultiPoint") == 0)
399
                                shapeType = FShape.POINT;
400
                        else if (geometryType.compareToIgnoreCase("MultiLineString") == 0)
401
                                shapeType = FShape.LINE;
402
                        else if (geometryType.compareToIgnoreCase("MultiPolygon") == 0)
403
                                shapeType = FShape.POLYGON;
404

    
405
                        dbld.setGeometryTypes(new int[]{shapeType});
406
                        rs.close();
407

    
408
                } catch (java.sql.SQLException e) {
409
                        dbld.setDefaultSRS("");
410
                        dbld.setGeometryTypes(new int[]{FShape.MULTI});
411
                        throw new ReadException("H2Utils.getTableEPSG_and_shapeType",e);
412
                }
413

    
414
        }
415

    
416
        static String getConnectionResourceID(String dbUrl,String dbUser){
417
                return H2Store.CONNECTION_STRING+";"+dbUrl+";"+dbUser;
418

    
419
        }
420

    
421

    
422
        static String getJDBCUrl(String host,String db){
423
                String url;
424
                url = "jdbc:h2:tcp://"+host;
425
                if (db == null || db == ""){
426
                        url=url+"/default";
427
                }else {
428
                        url=url+"/"+db;
429
                }
430

    
431
                return url;
432
        }
433

    
434
        static Connection getConnection(String dbUrl,String dbUser, String dbPass) throws InitializeException{
435
                //TODO: Aqu? habria que implementar la llamada
436
                //      al Resource Manager para comprobar si ya hay
437
                //                una connexion a la BD
438
                String connID = getConnectionResourceID(dbUrl, dbUser);
439

    
440
                Connection conn = null;
441
//                IResource res = ResourceManager.getResourceManager().getResource(connID);
442

    
443

    
444

    
445
                try {
446
                        Class.forName("org.h2.Driver");
447
                } catch (ClassNotFoundException e) {
448
                        throw new JDBCDriverNotFoundException("org.h2.Driver",e);
449
                }
450
                try {
451
                        conn = DriverManager.getConnection(dbUrl, dbUser, dbPass);
452
                        conn.setAutoCommit(false);
453

    
454
                } catch (java.sql.SQLException e1) {
455
                        throw new InitializeException("H2",e1);
456
                }
457
                //TODO: Registrar en el Resource manager
458
                // ResourceManager.getResourceManager().addResource(res);
459

    
460
                return conn;
461
        }
462

    
463

    
464
}