Statistics
| Revision:

root / trunk / extensions / extJDBC / src / com / iver / cit / gvsig / fmap / drivers / jdbc / mysql / MySQLDriver.java @ 29091

History | View | Annotate | Download (15 KB)

1
/*
2
 * Created on 04-mar-2005
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
package com.iver.cit.gvsig.fmap.drivers.jdbc.mysql;
45

    
46
import java.awt.geom.Rectangle2D;
47
import java.sql.ResultSet;
48
import java.sql.ResultSetMetaData;
49
import java.sql.SQLException;
50
import java.sql.Statement;
51
import java.util.ArrayList;
52

    
53
import org.apache.log4j.Logger;
54

    
55
import com.hardcode.gdbms.driver.exceptions.InitializeWriterException;
56
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
57
import com.hardcode.gdbms.engine.data.edition.DataWare;
58
import com.iver.cit.gvsig.fmap.core.IGeometry;
59
import com.iver.cit.gvsig.fmap.drivers.ConnectionJDBC;
60
import com.iver.cit.gvsig.fmap.drivers.DBException;
61
import com.iver.cit.gvsig.fmap.drivers.DBLayerDefinition;
62
import com.iver.cit.gvsig.fmap.drivers.DefaultJDBCDriver;
63
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
64
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
65
import com.iver.cit.gvsig.fmap.drivers.IConnection;
66
import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator;
67
import com.iver.cit.gvsig.fmap.drivers.WKBParser2;
68
import com.iver.cit.gvsig.fmap.edition.IWriteable;
69
import com.iver.cit.gvsig.fmap.edition.IWriter;
70

    
71
/**
72
 * @author FJP
73
 *
74
 * TODO To change the template for this generated type comment go to Window -
75
 * Preferences - Java - Code Generation - Code and Comments
76
 */
77
public class MySQLDriver extends DefaultJDBCDriver
78
                                                        implements IWriteable {
79

    
80
        private static Logger logger = Logger
81
                        .getLogger(MySQLDriver.class.getName());
82

    
83
        private WKBParser2 parser = new WKBParser2();
84

    
85
        private MySQLSpatialWriter writer = new MySQLSpatialWriter();
86

    
87
        private static final String[] GEOM_SQL_TYPE_NAMES ={
88
              "GEOMETRY",
89
              "POINT",
90
              "LINESTRING",
91
              "POLYGON",
92
              "MULTIPOINT",
93
              "MULTILINESTRING",
94
              "MULTIPOLYGON",
95
              "GEOMETRYCOLLECTION",
96
        };
97

    
98
        /*
99
         * private int fetch_min=-1; private int fetch_max=-1;
100
         */
101
        private Statement st;
102

    
103
        private String strAux;
104

    
105
        private String strEPSG = "-1";
106

    
107
        private String originalEPSG;
108

    
109
        private String completeWhere;
110

    
111
        /**
112
         * Don't have information about working area
113
         */
114
        private String sqlOrig;
115

    
116
        /**
117
         * Does have information about working area and order
118
         */
119
        private String sqlTotal;
120

    
121
        /**
122
         *
123
         */
124
        public MySQLDriver() {
125
        }
126

    
127
        /*
128
         * (non-Javadoc)
129
         *
130
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDriver#getDriverAttributes()
131
         */
132
        public DriverAttributes getDriverAttributes() {
133
                return null;
134
        }
135

    
136
        /*
137
         * (non-Javadoc)
138
         *
139
         * @see com.hardcode.driverManager.Driver#getName()
140
         */
141
        public String getName() {
142
                return "mySQL JDBC Driver";
143
        }
144

    
145
        /**
146
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShape(int)
147
         */
148
        public IGeometry getShape(int index) {
149
                IGeometry geom = null;
150
                boolean resul;
151
                try {
152
                        if (rs != null) {
153
                                rs.absolute(index + 1);
154
                                byte[] data = rs.getBytes(1);
155
                                geom = parser.parse(data);
156
                        }
157

    
158
                } catch (SQLException e) {
159
                        e.printStackTrace();
160
                }
161

    
162
                return geom;
163
        }
164

    
165
        /**
166
         * @param conn
167
         * @throws DBException
168
         */
169
        /*
170
         * (non-Javadoc)
171
         *
172
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialJDBCDriver#setData(java.sql.Connection,
173
         *      java.lang.String, java.lang.String, java.lang.String, int)
174
         */
175
        public void setData(IConnection conn, DBLayerDefinition lyrDef) throws DBException {
176
                this.conn = conn;
177
                setLyrDef(lyrDef);
178
                try {
179

    
180
                        // NO ESTA LISTO ESTO AUN EN mySQL, o no s? usuarlo getTableEPSG();
181

    
182
                        sqlOrig = "SELECT " + getTotalFields() + " FROM "
183
                                        + getLyrDef().getTableName() + " ";
184
                                        // + getLyrDef().getWhereClause();
185
                        completeWhere = getCompoundWhere(workingArea, strEPSG);
186
                        String sqlAux = sqlOrig + completeWhere + " ORDER BY "
187
                                        + getLyrDef().getFieldID();
188
                        logger.info("Cadena SQL:" + sqlAux);
189
                        sqlTotal = sqlAux;
190

    
191
                        st = ((ConnectionJDBC)conn).getConnection().createStatement(ResultSet.TYPE_FORWARD_ONLY,
192
                                        ResultSet.CONCUR_READ_ONLY);
193

    
194
                        rs = st.executeQuery(sqlTotal);
195
                        metaData = rs.getMetaData();
196
                        // Le pegamos un primera pasada para poder relacionar
197
                        // un campo de identificador ?nico (parecido al OID en
198
                        // postgresql) con el ?ndice dentro del recordset.
199
                        // Esto cuando haya ediciones, no es v?lido, y hay
200
                        // que refrescarlo.
201
                        doRelateID_FID();
202

    
203
                        writer.setCreateTable(false);
204
                        writer.setWriteAll(false);
205
                        writer.initialize(lyrDef);
206

    
207

    
208
                } catch (SQLException e) {
209
                          throw new DBException(e);
210
                } catch (InitializeWriterException e) {
211
                          throw new DBException(e);
212
                }
213
        }
214

    
215
        /*
216
         * (non-Javadoc)
217
         *
218
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDatabaseDriver#getGeometryIterator(java.lang.String)
219
         */
220
        public IFeatureIterator getFeatureIterator(String sql)
221
                        throws ReadDriverException {
222
                Statement st;
223
                MySqlFeatureIterator geomIterator = null;
224
                geomIterator = myGetFeatureIterator(sql);
225
                geomIterator.setLyrDef(getLyrDef());
226

    
227
                return geomIterator;
228
        }
229

    
230
        private MySqlFeatureIterator myGetFeatureIterator(String sql)
231
        throws ReadDriverException {
232
                Statement st;
233
                MySqlFeatureIterator geomIterator = null;
234
                try {
235
                        logger.debug(sql);
236
                        st = ((ConnectionJDBC)conn).getConnection().createStatement();
237
                        // st.setFetchSize(2000);
238
                        ResultSet rs = st.executeQuery(sql);
239
                        geomIterator = new MySqlFeatureIterator(rs);
240
                        geomIterator.setLyrDef(getLyrDef());
241
                } catch (SQLException e) {
242
//                        e.printStackTrace();
243
//                        SqlDriveExceptionType type = new SqlDriveExceptionType();
244
//                        type.setDriverName("MySQL Driver");
245
//                        type.setSql(sql);
246
//                        type.setLayerName(getTableName());
247
//                        type.setSchema(null);
248
                        throw new ReadDriverException("MySQL Driver",e);
249
//                        throw new com.iver.cit.gvsig.fmap.DriverException(e);
250
                }
251

    
252
                return geomIterator;
253
        }
254

    
255
        /*
256
         * (non-Javadoc)
257
         *
258
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDatabaseDriver#getGeometryIterator(java.awt.geom.Rectangle2D)
259
         */
260
        public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG)
261
                        throws ReadDriverException {
262
                if (workingArea != null)
263
                        r = r.createIntersection(workingArea);
264
                String sqlAux = sqlOrig + getCompoundWhere(r, strEPSG);
265

    
266
                return getFeatureIterator(sqlAux);
267
        }
268

    
269
        /**
270
         * Le pasas el rect?ngulo que quieres pedir. La primera vez es el
271
         * workingArea, y las siguientes una interseccion de este rectangulo con el
272
         * workingArea
273
         *
274
         * @param r
275
         * @param strEPSG
276
         * @return
277
         */
278
        private String getCompoundWhere(Rectangle2D r, String strEPSG) {
279
                if (r == null)
280
                        return getWhereClause();
281

    
282
                double xMin = r.getMinX();
283
                double yMin = r.getMinY();
284
                double xMax = r.getMaxX();
285
                double yMax = r.getMaxY();
286

    
287
                String wktBox = "GeomFromText('LINESTRING(" + xMin + " " + yMin + ", "
288
                                + xMax + " " + yMin + ", " + xMax + " " + yMax + ", " + xMin
289
                                + " " + yMax + ")', '" + strEPSG + "')";
290
                String sqlAux;
291
                if (getWhereClause().startsWith("WHERE"))
292
                        sqlAux = getWhereClause() + " AND " +"MBRIntersects(" + wktBox + ", " + getLyrDef().getFieldGeometry() + ")";
293
                else
294
                        sqlAux = "WHERE MBRIntersects(" + wktBox + ", " + getLyrDef().getFieldGeometry() + ")";
295
                return sqlAux;
296
        }
297

    
298
        public void open() {
299
                // TODO Auto-generated method stub
300

    
301
        }
302

    
303
        /**
304
         * @see com.iver.cit.gvsig.fmap.drivers.IVectorialDatabaseDriver#getConnectionStringBeginning()
305
         */
306
        public String getConnectionStringBeginning() {
307
                return "jdbc:mysql:";
308
        }
309

    
310
        static {
311
                try {
312
                        Class.forName("com.mysql.jdbc.Driver");
313
                } catch (ClassNotFoundException e) {
314
                        throw new RuntimeException(e);
315
                }
316
        }
317

    
318
        /**
319
         * @see com.iver.cit.gvsig.fmap.drivers.IVectorialDatabaseDriver#getGeometryField(java.lang.String)
320
         */
321
        public String getGeometryField(String fieldName) {
322
                return "ASBINARY(" + fieldName + ")";
323
        }
324

    
325
        /**
326
         * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#getPrimaryKeys()
327
         */
328
        public int[] getPrimaryKeys()
329
                        throws ReadDriverException {
330
                return new int[] { getLyrDef().getIdFieldID() - 2 };
331
        }
332

    
333
        /**
334
         * @see com.iver.cit.gvsig.fmap.drivers.IVectorialJDBCDriver#getDefaultPort()
335
         */
336
        public int getDefaultPort() {
337
                return 3306;
338
        }
339

    
340
        /**
341
         * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#write(com.hardcode.gdbms.engine.data.edition.DataWare)
342
         */
343
        public void write(DataWare arg0){
344
                // TODO Auto-generated method stub
345

    
346
        }
347

    
348
        private void getTableEPSG() {
349
                try {
350
                        Statement stAux = ((ConnectionJDBC)conn).getConnection().createStatement();
351

    
352
                        String sql = "SELECT SRID(" + getLyrDef().getFieldGeometry() + ") FROM " + getTableName()
353
                                        + " LIMIT 1;";
354
                        ResultSet rs = stAux.executeQuery(sql);
355
                        rs.next();
356
                        originalEPSG = "" + rs.getInt(1);
357
                        rs.close();
358
                } catch (SQLException e) {
359
                        // TODO Auto-generated catch block
360
                        e.printStackTrace();
361
                }
362

    
363
        }
364

    
365
        public String getSqlTotal() {
366
                return sqlTotal;
367
        }
368

    
369
        /**
370
         * @return Returns the completeWhere.
371
         */
372
        public String getCompleteWhere() {
373
                return completeWhere;
374
        }
375

    
376
        /*
377
         * (non-Javadoc)
378
         *
379
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDatabaseDriver#getFeatureIterator(java.awt.geom.Rectangle2D,
380
         *      java.lang.String, java.lang.String[])
381
         */
382
        public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG,
383
                        String[] alphaNumericFieldsNeeded) throws ReadDriverException {
384

    
385
                DBLayerDefinition lyrDef = getLyrDef();
386
                DBLayerDefinition clonedLyrDef = cloneLyrDef(lyrDef);
387
                ArrayList<FieldDescription> myFieldsDesc = new ArrayList<FieldDescription>(); // = new FieldDescription[alphaNumericFieldsNeeded.length+1];
388

    
389
                if (workingArea != null)
390
                        r = r.createIntersection(workingArea);
391

    
392
                String strAux = getGeometryField(lyrDef.getFieldGeometry());
393
                boolean found = false;
394
                if (alphaNumericFieldsNeeded != null) {
395
                        for (int i = 0; i < alphaNumericFieldsNeeded.length; i++) {
396
                                strAux = strAux + ", " + alphaNumericFieldsNeeded[i];
397
                                if (alphaNumericFieldsNeeded[i].
398
                                                equals(lyrDef.getFieldID())){
399
                                        found = true;
400
                                        clonedLyrDef.setIdFieldID(i);
401
                                }
402

    
403

    
404
                                FieldDescription[] fieldsDesc = lyrDef.getFieldsDesc();
405
                                for (int j =0; j < fieldsDesc.length; j++){
406
                                        if (fieldsDesc[j].getFieldName().
407
                                                        equals(alphaNumericFieldsNeeded[i])){
408
                                                myFieldsDesc.add(fieldsDesc[j]);
409
                                        }
410
                                }
411

    
412

    
413
                        }
414
                }
415
                // Nos aseguramos de pedir siempre el campo ID
416
                if (found == false) {
417
                        strAux = strAux + ", " + lyrDef.getFieldID();
418
                        myFieldsDesc.add(lyrDef.getFieldsDesc()[lyrDef.getIdField(
419
                                        lyrDef.getFieldID())]);
420
                        clonedLyrDef.setIdFieldID(myFieldsDesc.size()-1);
421
                }
422
                clonedLyrDef.setFieldsDesc( (FieldDescription[])myFieldsDesc.toArray(new FieldDescription[]{}) );
423

    
424

    
425
                String sqlProv = "SELECT " + strAux + " FROM "
426
                                + lyrDef.getTableName() + " ";
427
                                // + getLyrDef().getWhereClause();
428

    
429
                String sqlAux;
430
                sqlAux = sqlProv + getCompoundWhere(r, strEPSG);
431

    
432
                System.out.println("SqlAux getFeatureIterator = " + sqlAux);
433
                MySqlFeatureIterator geomIterator = null;
434
                geomIterator = myGetFeatureIterator(sqlAux);
435
                geomIterator.setLyrDef(clonedLyrDef);
436
                return geomIterator;
437
        }
438

    
439
        public boolean isWritable() {
440
                return true;
441
        }
442

    
443
        public IWriter getWriter() {
444
                return writer;
445
        }
446

    
447
public String[] getTableFields(IConnection conex, String table) throws DBException {
448
                try{
449
                Statement st = ((ConnectionJDBC)conex).getConnection().createStatement();
450
        // ResultSet rs = dbmd.getTables(catalog, null, dbLayerDefinition.getTable(), null);
451
                ResultSet rs = st.executeQuery("select * from " + table + " LIMIT 1");
452
                ResultSetMetaData rsmd = rs.getMetaData();
453

    
454
                String[] ret = new String[rsmd.getColumnCount()];
455

    
456
                for (int i = 0; i < ret.length; i++) {
457
                        ret[i] = rsmd.getColumnName(i+1);
458
                }
459

    
460
                return ret;
461
                }catch (SQLException e) {
462
                        throw new DBException(e);
463
                }
464
        }
465

    
466
private DBLayerDefinition cloneLyrDef(DBLayerDefinition lyrDef){
467
        DBLayerDefinition clonedLyrDef = new DBLayerDefinition();
468

    
469
        clonedLyrDef.setName(lyrDef.getName());
470
        clonedLyrDef.setFieldsDesc(lyrDef.getFieldsDesc());
471

    
472
        clonedLyrDef.setShapeType(lyrDef.getShapeType());
473
        clonedLyrDef.setProjection(lyrDef.getProjection());
474

    
475
        clonedLyrDef.setConnection(lyrDef.getConnection());
476
        clonedLyrDef.setCatalogName(lyrDef.getCatalogName());
477
        clonedLyrDef.setSchema(lyrDef.getSchema());
478
        clonedLyrDef.setTableName(lyrDef.getTableName());
479

    
480
        clonedLyrDef.setFieldID(lyrDef.getFieldID());
481
        clonedLyrDef.setFieldGeometry(lyrDef.getFieldGeometry());
482
        clonedLyrDef.setWhereClause(lyrDef.getWhereClause());
483
        clonedLyrDef.setWorkingArea(lyrDef.getWorkingArea());
484
        clonedLyrDef.setSRID_EPSG(lyrDef.getSRID_EPSG());
485
        clonedLyrDef.setClassToInstantiate(lyrDef.getClassToInstantiate());
486

    
487
        clonedLyrDef.setIdFieldID(lyrDef.getIdFieldID());
488
        clonedLyrDef.setDimension(lyrDef.getDimension());
489
        clonedLyrDef.setHost(lyrDef.getHost());
490
        clonedLyrDef.setPort(lyrDef.getPort());
491
        clonedLyrDef.setDataBase(lyrDef.getDataBase());
492
        clonedLyrDef.setUser(lyrDef.getUser());
493
        clonedLyrDef.setPassword(lyrDef.getPassword());
494
        clonedLyrDef.setConnectionName(lyrDef.getConnectionName());
495
        return clonedLyrDef;
496
}
497

    
498

    
499
/**
500
 * Gets the table's possible geometry fields. By default, all fields can be geometry
501
 * fields. It should be overwritten by subclasses.
502
 *
503
 * @param conn conenction object
504
 * @param table_name table name
505
 * @return the table's possible geometry fields
506
 * @throws SQLException
507
 */
508
public String[] getGeometryFieldsCandidates(IConnection conn, String table_name) throws DBException {
509
        try {
510
                Statement st = ((ConnectionJDBC)conn).getConnection().createStatement();
511
                ResultSet rs = st.executeQuery("select * from " + table_name + " where false");
512
                ResultSetMetaData rsmd = rs.getMetaData();
513
                ArrayList names = new ArrayList();
514
                ResultSetMetaData rsMeta = rs.getMetaData();
515
                boolean isGeo;
516
                for (int i = 0; i < rsMeta.getColumnCount(); i++) {
517
                        isGeo = false;
518
                        System.out.println(rsMeta.getColumnName(i+1));
519
                        for (int j = 0;j< GEOM_SQL_TYPE_NAMES.length;j++){
520
                                rsMeta.getColumnType(i+1);
521
                                System.out.println(rsMeta.getColumnTypeName(i+1));
522
                                if (GEOM_SQL_TYPE_NAMES[j].equalsIgnoreCase(rsMeta.getColumnTypeName(i+1))){
523
                                        isGeo = true;
524
                                        break;
525
                                }
526
                        }
527
                        if (isGeo || "UNKNOWN".equalsIgnoreCase(rsMeta.getColumnTypeName(i+1))){
528
                                names.add(rsMeta.getColumnName(i+1));
529
                        }
530
                }
531
                rsMeta = null;
532
                rs.close(); st.close();
533
                return (String[]) names.toArray(new String[names.size()]);
534
            } catch (SQLException e) {
535
                        throw new DBException(e);
536
                }
537
}
538

    
539
}