Statistics
| Revision:

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

History | View | Annotate | Download (15.4 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.AttributeDescriptor;
21
import org.gvsig.data.vectorial.IFeature;
22
import org.gvsig.data.vectorial.IFeatureAttributeDescriptor;
23
import org.gvsig.data.vectorial.IFeatureType;
24
import org.gvsig.data.vectorial.IsNotAttributeSettingException;
25

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

    
31
public class H2Utils {
32

    
33

    
34

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

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

    
55

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

    
70
                }
71
                return schema;
72
        }
73

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

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

    
84
                try {
85

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

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

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

    
102
                        String colName;
103
                        int i;
104

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

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

    
141
                                }
142
                        }
143

    
144
                        rs.close();
145
                        rsAllMeta.close();
146
                } catch (java.sql.SQLException e) {
147
                        // TODO Auto-generated catch block
148
                        throw new SQLException(sql,"getFeatureType",e);
149
                } catch (IsNotAttributeSettingException e) {
150
                        e.printStackTrace();
151
                }
152

    
153
        }
154

    
155
        static DBFeatureType getFeatureType(Connection conn,H2StoreParameters params) throws ReadException{
156
                DBFeatureType featureType = new DBFeatureType();
157

    
158

    
159
                loadFieldsToFeatureType(conn, params, featureType);
160

    
161

    
162
                if (params.getFieldsId() == null || params.getFieldsId().length == 0){
163
                        featureType.setFieldsId(loadFieldsId(conn,params));
164
                } else{
165
                        featureType.setFieldsId(params.getFieldsId());
166
                }
167

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

    
175
                        }
176

    
177
                        featureType.setDefaultGeometry(params.getGeometryField());
178
                }
179

    
180
                return featureType;
181

    
182
        }
183

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

    
200
                if (params.getSchema() == null || params.getSchema() == ""){
201
                        sql.append(getDefaultSchema(conn, params.getDb()));
202
                } else{
203
                        sql.append(params.getSchema());
204
                }
205

    
206

    
207
                if (params.getCatalog() == null || params.getCatalog() == ""){
208
                        if (params.getDb() != null && params.getDb() != ""){
209
                                sql.append("' AND table_catalog like '");
210
                                sql.append(params.getDb());
211
                        }
212
                } else {
213
                        sql.append("' AND table_catalog like '");
214
                        sql.append(params.getCatalog());
215
                }
216

    
217

    
218

    
219
                sql.append("' AND index_type_name='PRIMARY KEY'");
220

    
221
                try {
222
                        st = conn.createStatement();
223
                        rs = st.executeQuery(sql.toString());
224
                        while (rs.next()){
225
                                list.add(rs.getString(1));
226
                        }
227
                        rs.close();
228
                        st.close();
229

    
230
                } catch (java.sql.SQLException e) {
231
                        throw new ReadException(params.getDataStoreName(),e);
232
                }
233

    
234
                String[] x = new String[] {""};
235
                return (String[])list.toArray(x);
236

    
237
        }
238

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

    
310
                return column;
311

    
312
        }
313

    
314
        private static AttributeDescriptor getAttributeFromJDBC(Connection conn, ResultSet rsMetadata) throws SQLException{
315
                JDBCAttributeDescriptor column= new JDBCAttributeDescriptor();
316
                try {
317
                        column.loading();
318
                        column.setName(rsMetadata.getString("COLUMN_NAME"));
319
                        column.setSqlType(rsMetadata.getInt("DATA_TYPE"));
320
                        switch (rsMetadata.getInt("DATA_TYPE")) {
321
                        case java.sql.Types.INTEGER:
322
                                column.setType(IFeatureAttributeDescriptor.TYPE_INT);
323
                                break;
324
                        case java.sql.Types.BIGINT:
325
                                column.setType(IFeatureAttributeDescriptor.TYPE_LONG);
326
                                break;
327
                        case java.sql.Types.REAL:
328
                                column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
329
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
330
                                column.setPrecision(rsMetadata.getInt("NUMERIC_PRECISION"));
331
                                break;
332
                        case java.sql.Types.DOUBLE:
333
                                column.setType(IFeatureAttributeDescriptor.TYPE_DOUBLE);
334
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
335
                                column.setPrecision(rsMetadata.getInt("NUMERIC_PRECISION"));
336
                                break;
337
                        case java.sql.Types.CHAR:
338
                                column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
339
//                                column.setSize(rsMetadata.getInt("COLUMN_SIZE"));
340
                                column.setSize(rsMetadata.getInt("CHARACTER_MAXIMUM_LENGTH"));
341
                                break;
342
                        case java.sql.Types.VARCHAR:
343
                                column.setType(IFeatureAttributeDescriptor.TYPE_STRING);
344
//                                column.setSize(rsMetadata.getInt("COLUMN_SIZE"));
345
                                column.setSize(rsMetadata.getInt("CHARACTER_MAXIMUM_LENGTH"));
346

    
347
                                break;
348
                        case java.sql.Types.FLOAT:
349
                                column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
350
//                                column.setSize(rsMetadata.getInt("COLUMN_SIZE"));
351
                                column.setSize(rsMetadata.getInt("CHARACTER_MAXIMUM_LENGTH"));
352
                                break;
353
                        case java.sql.Types.DECIMAL:
354
                                column.setType(IFeatureAttributeDescriptor.TYPE_FLOAT);
355
//                                column.setSize(rsMetadata.getInt("COLUMN_SIZE"));
356
                                column.setSize(rsMetadata.getInt("CHARACTER_MAXIMUM_LENGTH"));
357
//                                column.setPrecision(rsMetadata.getInt("DECIMAL_DIGITS"));
358
                                column.setPrecision(rsMetadata.getInt("NUMERIC_PRECISION"));
359
                                break;
360
                        case java.sql.Types.DATE:
361
                                column.setType(IFeatureAttributeDescriptor.TYPE_DATE);
362
                                break;
363
                        case java.sql.Types.BOOLEAN:
364
                                column.setType(IFeatureAttributeDescriptor.TYPE_BOOLEAN);
365
                                break;
366
                        default:
367
                                //FIXME: Falta comprobar si es geometrica!!!
368
                                column.setType(IFeatureAttributeDescriptor.TYPE_OBJECT);
369
                                break;
370
                        }
371

    
372
                        column.setDefaultValue(rsMetadata.getObject("COLUMN_DEFAULT"));
373
                        column.setAllowNull(rsMetadata.getBoolean("IS_NULLABLE"));
374
                        column.stopLoading();
375
                } catch (java.sql.SQLException e){
376
                        throw new SQLException("","load attribute definition",e);
377
                } catch (IsNotAttributeSettingException e) {
378
                        e.printStackTrace();
379
                }
380

    
381
                return column;
382

    
383
        }
384

    
385

    
386

    
387
        static void initializeTableEPSG_and_shapeType(Connection conn,String tableID, DBFeatureType dbld) throws ReadException {
388
                try {
389
                        Statement stAux = conn.createStatement();
390

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

    
395
                        ResultSet rs = stAux.executeQuery(sql);
396
                        if(!rs.next()){
397
                                dbld.setDefaultSRS("");
398
                                dbld.setGeometryTypes(new int[]{FShape.MULTI});
399
                                return;
400
                        }
401
                        dbld.setDefaultSRS("EPSG:"+rs.getInt(1));
402

    
403
                        String geometryType = rs.getString(2);
404
                        int shapeType = FShape.MULTI;
405
                        if (geometryType.compareToIgnoreCase("Point") == 0)
406
                                shapeType = FShape.POINT;
407
                        else if (geometryType.compareToIgnoreCase("LineString") == 0)
408
                                shapeType = FShape.LINE;
409
                        else if (geometryType.compareToIgnoreCase("Polygon") == 0)
410
                                shapeType = FShape.POLYGON;
411
                        else if (geometryType.compareToIgnoreCase("MultiPoint") == 0)
412
                                shapeType = FShape.POINT;
413
                        else if (geometryType.compareToIgnoreCase("MultiLineString") == 0)
414
                                shapeType = FShape.LINE;
415
                        else if (geometryType.compareToIgnoreCase("MultiPolygon") == 0)
416
                                shapeType = FShape.POLYGON;
417

    
418
                        dbld.setGeometryTypes(new int[]{shapeType});
419
                        rs.close();
420

    
421
                } catch (java.sql.SQLException e) {
422
                        dbld.setDefaultSRS("");
423
                        dbld.setGeometryTypes(new int[]{FShape.MULTI});
424
                        throw new ReadException("H2Utils.getTableEPSG_and_shapeType",e);
425
                }
426

    
427
        }
428

    
429
        static String getConnectionResourceID(String dbUrl,String dbUser){
430
                return H2Store.CONNECTION_STRING+";"+dbUrl+";"+dbUser;
431

    
432
        }
433

    
434

    
435
        static String getJDBCUrl(String host,String db){
436
                String url;
437
                url = "jdbc:h2:tcp://"+host;
438
                if (db == null || db == ""){
439
                        url=url+"/default";
440
                }else {
441
                        url=url+"/"+db;
442
                }
443

    
444
                return url;
445
        }
446

    
447
        static Connection getConnection(String dbUrl,String dbUser, String dbPass) throws InitializeException{
448
                //TODO: Aqu? habria que implementar la llamada
449
                //      al Resource Manager para comprobar si ya hay
450
                //                una connexion a la BD
451
                String connID = getConnectionResourceID(dbUrl, dbUser);
452

    
453
                Connection conn = null;
454
//                IResource res = ResourceManager.getResourceManager().getResource(connID);
455

    
456

    
457

    
458
                try {
459
                        Class.forName("org.h2.Driver");
460
                } catch (ClassNotFoundException e) {
461
                        throw new JDBCDriverNotFoundException("org.h2.Driver",e);
462
                }
463
                try {
464
                        conn = DriverManager.getConnection(dbUrl, dbUser, dbPass);
465
//                        conn.setAutoCommit(false);
466

    
467
                } catch (java.sql.SQLException e1) {
468
                        throw new InitializeException("H2",e1);
469
                }
470
                //TODO: Registrar en el Resource manager
471
                // ResourceManager.getResourceManager().addResource(res);
472

    
473
                return conn;
474
        }
475

    
476

    
477
}