Statistics
| Revision:

svn-gvsig-desktop / branches / v10 / extensions / extJDBC / src / com / iver / cit / gvsig / fmap / drivers / jdbc / postgis / PostGisDriver.java @ 20385

History | View | Annotate | Download (28 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.postgis;
45

    
46
import java.awt.geom.Rectangle2D;
47
import java.io.IOException;
48
import java.math.BigDecimal;
49
import java.nio.ByteBuffer;
50
import java.sql.Connection;
51
import java.sql.Date;
52
import java.sql.ResultSet;
53
import java.sql.ResultSetMetaData;
54
import java.sql.SQLException;
55
import java.sql.Statement;
56
import java.sql.Time;
57
import java.sql.Timestamp;
58
import java.sql.Types;
59
import java.util.ArrayList;
60
import java.util.Hashtable;
61

    
62
import org.apache.log4j.Logger;
63
import org.postgis.PGbox2d;
64
import org.postgis.PGbox3d;
65

    
66
import com.hardcode.gdbms.engine.data.edition.DataWare;
67
import com.hardcode.gdbms.engine.values.Value;
68
import com.hardcode.gdbms.engine.values.ValueFactory;
69
import com.iver.andami.messages.NotificationManager;
70
import com.iver.cit.gvsig.fmap.DriverException;
71
import com.iver.cit.gvsig.fmap.SqlDriveExceptionType;
72
import com.iver.cit.gvsig.fmap.core.FShape;
73
import com.iver.cit.gvsig.fmap.core.ICanReproject;
74
import com.iver.cit.gvsig.fmap.core.IGeometry;
75
import com.iver.cit.gvsig.fmap.drivers.ConnectionJDBC;
76
import com.iver.cit.gvsig.fmap.drivers.DBException;
77
import com.iver.cit.gvsig.fmap.drivers.DBLayerDefinition;
78
import com.iver.cit.gvsig.fmap.drivers.DefaultJDBCDriver;
79
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
80
import com.iver.cit.gvsig.fmap.drivers.IConnection;
81
import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator;
82
import com.iver.cit.gvsig.fmap.drivers.TableDefinition;
83
import com.iver.cit.gvsig.fmap.drivers.WKBParser2;
84
import com.iver.cit.gvsig.fmap.drivers.XTypes;
85
import com.iver.cit.gvsig.fmap.edition.EditionException;
86
import com.iver.cit.gvsig.fmap.edition.IWriteable;
87
import com.iver.cit.gvsig.fmap.edition.IWriter;
88

    
89
/**
90
 * @author FJP
91
 *
92
 * TODO To change the template for this generated type comment go to Window -
93
 * Preferences - Java - Code Generation - Code and Comments
94
 */
95
public class PostGisDriver extends DefaultJDBCDriver implements ICanReproject, IWriteable {
96
        private static Logger logger = Logger.getLogger(PostGisDriver.class
97
                        .getName());
98

    
99
        private static int FETCH_SIZE = 5000;
100

    
101
        // To avoid problems when using wkb_cursor with same layer.
102
        // I mean, when you add twice or more the same layer using
103
        // the same connection
104

    
105
        private static int CURSOR_ID = 0;
106
        private int myCursorId;
107
        private PostGISWriter writer = new PostGISWriter();
108
        private WKBParser2 parser = new WKBParser2();
109
        private int fetch_min = -1;
110
        private int fetch_max = -1;
111
        private String sqlOrig;
112

    
113
        /**
114
         * Used by setAbsolutePosition
115
         */
116
        private String sqlTotal;
117

    
118
        private String strEPSG = null;
119

    
120
        private String originalEPSG = null;
121

    
122
        private Rectangle2D fullExtent = null;
123

    
124
        private String strAux;
125

    
126
        private String completeWhere;
127

    
128
        private String provCursorName = null;
129

    
130
        int numProvCursors = 0;
131

    
132
        boolean bShapeTypeRevised = false;
133

    
134
        private int actual_position;
135

    
136
        static {
137
                try {
138
                        Class.forName("org.postgresql.Driver");
139
                } catch (ClassNotFoundException e) {
140
                        throw new RuntimeException(e);
141
                }
142
        }
143

    
144
        /**
145
         *
146
         */
147
        public PostGisDriver() {
148
                // To avoid problems when using wkb_cursor with same layer.
149
                // I mean, when you add twice or more the same layer using
150
                // the same connection
151
                CURSOR_ID++;
152
                myCursorId = CURSOR_ID;
153
        }
154

    
155
        /*
156
         * (non-Javadoc)
157
         *
158
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDriver#getDriverAttributes()
159
         */
160
        public DriverAttributes getDriverAttributes() {
161
                return null;
162
        }
163

    
164
        /*
165
         * (non-Javadoc)
166
         *
167
         * @see com.hardcode.driverManager.Driver#getName()
168
         */
169
        public String getName() {
170
                return "PostGIS JDBC Driver";
171
        }
172

    
173
        /**
174
         * @throws IOException
175
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShape(int)
176
         */
177
        public IGeometry getShape(int index) throws IOException {
178
                IGeometry geom = null;
179
                boolean resul;
180
                try {
181
                        setAbsolutePosition(index);
182
                        // strAux = rs.getString(1);
183
                        // geom = parser.read(strAux);
184
                        if (rs != null) {
185
                                byte[] data = rs.getBytes(1);
186
                                if (data == null) // null geometry.
187
                                        return null;
188
                                geom = parser.parse(data);
189
                        }
190
                } catch (SQLException e) {
191
                        throw new IOException(e.getMessage());
192
                }
193

    
194
                return geom;
195
        }
196

    
197
        /**
198
         * First, the geometry field. After, the rest of fields
199
         *
200
         * @return
201
         */
202
        /*
203
         * public String getTotalFields() { String strAux = "AsBinary(" +
204
         * getLyrDef().getFieldGeometry() + ")"; String[] fieldNames =
205
         * getLyrDef().getFieldNames(); for (int i=0; i< fieldNames.length; i++) {
206
         * strAux = strAux + ", " + fieldNames[i]; } return strAux; }
207
         */
208

    
209
        /**
210
         * Antes de llamar a esta funci?n hay que haber fijado el workingArea si se
211
         * quiere usar.
212
         *
213
         * @param conn
214
         * @throws DBException
215
         */
216
        public void setData(IConnection conn, DBLayerDefinition lyrDef) throws DBException {
217
                this.conn = conn;
218
                // TODO: Deber?amos poder quitar Connection de la llamada y meterlo
219
                // en lyrDef desde el principio.
220

    
221
                lyrDef.setConnection(conn);
222
                setLyrDef(lyrDef);
223

    
224
                getTableEPSG_and_shapeType(conn, lyrDef);
225

    
226
                getLyrDef().setSRID_EPSG(originalEPSG);
227

    
228
                try {
229
                        ((ConnectionJDBC)conn).getConnection().setAutoCommit(false);
230
                        sqlOrig = "SELECT " + getTotalFields() + " FROM "
231
                                        + getLyrDef().getComposedTableName() + " ";
232
                                        // + getLyrDef().getWhereClause();
233
                        if (canReproject(strEPSG)) {
234
                                completeWhere = getCompoundWhere(sqlOrig, workingArea, strEPSG);
235
                        } else {
236
                                completeWhere = getCompoundWhere(sqlOrig, workingArea,
237
                                                originalEPSG);
238
                        }
239
                        // completeWhere = getLyrDef().getWhereClause() + completeWhere;
240

    
241
                        String sqlAux = sqlOrig + completeWhere + " ORDER BY "
242
                        + getLyrDef().getFieldID();
243

    
244
                        sqlTotal = sqlAux;
245
                        logger.info("SQL> " + sqlAux);
246
                        st = ((ConnectionJDBC)conn).getConnection().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
247
                                        ResultSet.CONCUR_READ_ONLY);
248
                        st.setFetchSize(FETCH_SIZE);
249
                        myCursorId++;
250
                        st.execute("declare " + getTableName() + myCursorId + "_wkb_cursor binary scroll cursor with hold for " + sqlAux);
251
                        rs = st.executeQuery("fetch forward " + FETCH_SIZE
252
                                        + " in " + getTableName() + myCursorId + "_wkb_cursor");
253
                        fetch_min = 0;
254
                        fetch_max = FETCH_SIZE - 1;
255
                        actual_position = 0;
256
                        metaData = rs.getMetaData();
257
                        doRelateID_FID();
258

    
259
                        writer.setCreateTable(false);
260
                        writer.setWriteAll(false);
261
                        writer.initialize(lyrDef);
262

    
263

    
264
                } catch (SQLException e) {
265
                        throw new DBException(e);
266
                } catch (EditionException e) {
267
                        throw new DBException(e);
268
                } catch (Exception e) {
269
                        throw new DBException(e);
270
                }
271
        }
272

    
273
        /**
274
         * @throws IOException
275
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getFullExtent()
276
         */
277
        public Rectangle2D getFullExtent() throws IOException {
278
                if (fullExtent == null) {
279
                        try {
280
                                Statement s = ((ConnectionJDBC)conn).getConnection().createStatement();
281
                                ResultSet r = s.executeQuery("SELECT extent("
282
                                                + getLyrDef().getFieldGeometry()
283
                                                + ") AS FullExtent FROM " + getLyrDef().getComposedTableName()
284
                                                + " " + getCompleteWhere());
285
                                r.next();
286
                                String strAux = r.getString(1);
287
                                System.out.println("fullExtent = " + strAux);
288
                                if (strAux == null)
289
                                {
290
                                        logger.debug("La capa " + getLyrDef().getName() + " no tiene FULLEXTENT");
291
                                        return null;
292
                                }
293
                                if (strAux.startsWith("BOX3D")) {
294
                                        PGbox3d regeom = new PGbox3d(strAux);
295
                                        double x = regeom.getLLB().x;
296
                                        double y = regeom.getLLB().y;
297
                                        double w = regeom.getURT().x - x;
298
                                        double h = regeom.getURT().y - y;
299
                                        fullExtent = new Rectangle2D.Double(x, y, w, h);
300
                                } else {
301
                                        PGbox2d regeom = new PGbox2d(strAux);
302
                                        double x = regeom.getLLB().x;
303
                                        double y = regeom.getLLB().y;
304
                                        double w = regeom.getURT().x - x;
305
                                        double h = regeom.getURT().y - y;
306
                                        fullExtent = new Rectangle2D.Double(x, y, w, h);
307
                                }
308
                        } catch (SQLException e) {
309
                                throw new IOException(e.getMessage());
310
                        }
311

    
312
                }
313
                return fullExtent;
314
        }
315

    
316
        /*
317
         * (non-Javadoc)
318
         *
319
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDatabaseDriver#getGeometryIterator(java.lang.String)
320
         */
321
        public IFeatureIterator getFeatureIterator(String sql)
322
                        throws com.iver.cit.gvsig.fmap.DriverException {
323
                PostGisFeatureIterator geomIterator = null;
324
                try {
325
                        // st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
326
                        // ResultSet.CONCUR_READ_ONLY);
327

    
328

    
329
                        if (provCursorName != null) {
330
                                /* st.execute("BEGIN");
331
                                st.execute("CLOSE " + provCursorName);
332
                                bCursorActivo = false;
333
                                st.execute("COMMIT"); */
334
                                numProvCursors++;
335
                        }
336
                        // st.execute("BEGIN");
337
                        provCursorName = getTableName() + myCursorId + "wkb_cursor_prov_" + System.currentTimeMillis() + "" + numProvCursors;
338

    
339
                        // st.execute("BEGIN");
340
                        bCursorActivo = true;
341
                        // ResultSet rs = st.executeQuery(sql);
342
                        geomIterator = new PostGisFeatureIterator(((ConnectionJDBC)conn).getConnection(), provCursorName, sql);
343
                        geomIterator.setLyrDef(getLyrDef());
344
                } catch (SQLException e) {
345
                        e.printStackTrace();
346
                        SqlDriveExceptionType type = new SqlDriveExceptionType();
347
            type.setDriverName("PostGIS Driver");
348
            type.setSql(sql);
349
            type.setLayerName(getTableName());
350
            type.setSchema(null);
351
            throw new com.iver.cit.gvsig.fmap.DriverException(e, type);
352
//                        throw new DriverException(e);
353
                        // return null;
354
                }
355

    
356
                return geomIterator;
357
        }
358

    
359
        public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG)
360
                        throws DriverException {
361
                if (workingArea != null)
362
                        r = r.createIntersection(workingArea);
363

    
364
                String sqlAux;
365
                if (canReproject(strEPSG)) {
366
                        sqlAux = sqlOrig + getCompoundWhere(sqlOrig, r, strEPSG);
367
                } else {
368
                        sqlAux = sqlOrig + getCompoundWhere(sqlOrig, r, originalEPSG);
369
                }
370

    
371
                System.out.println("SqlAux getFeatureIterator = " + sqlAux);
372

    
373
                return getFeatureIterator(sqlAux);
374
        }
375

    
376
        /**
377
         * Le pasas el rect?ngulo que quieres pedir. La primera vez es el
378
         * workingArea, y las siguientes una interseccion de este rectangulo con el
379
         * workingArea
380
         *
381
         * @param r
382
         * @param strEPSG
383
         * @return
384
         */
385
        private String getCompoundWhere(String sql, Rectangle2D r, String strEPSG) {
386
                if (r == null)
387
                        return getWhereClause();
388

    
389
                double xMin = r.getMinX();
390
                double yMin = r.getMinY();
391
                double xMax = r.getMaxX();
392
                double yMax = r.getMaxY();
393
                String wktBox = "GeometryFromText('LINESTRING(" + xMin + " " + yMin
394
                                + ", " + xMax + " " + yMin + ", " + xMax + " " + yMax + ", "
395
                                + xMin + " " + yMax + ")', " + strEPSG + ")";
396
                String sqlAux;
397
                if (getWhereClause().indexOf("WHERE") != -1)
398
                        sqlAux = getWhereClause() + " AND " + getLyrDef().getFieldGeometry() + " && " + wktBox;
399
                else
400
                        sqlAux = "WHERE " + getLyrDef().getFieldGeometry() + " && "
401
                                        + wktBox;
402
                return sqlAux;
403
        }
404

    
405
        /**
406
         * @see com.iver.cit.gvsig.fmap.drivers.IVectorialDatabaseDriver#getConnectionStringBeginning()
407
         */
408
        public String getConnectionStringBeginning() {
409
                return "jdbc:postgresql:";
410
        }
411

    
412
        /*
413
         * (non-Javadoc)
414
         *
415
         * @see com.iver.cit.gvsig.fmap.drivers.DefaultDBDriver#getFieldValue(long,
416
         *      int)
417
         */
418
        public Value getFieldValue(long rowIndex, int idField)
419
                        throws com.hardcode.gdbms.engine.data.driver.DriverException {
420
                boolean resul;
421
                // EL ABSOLUTE NO HACE QUE SE VUELVAN A LEER LAS
422
                // FILAS, ASI QUE MONTAMOS ESTA HISTORIA PARA QUE
423
                // LO HAGA
424
                // System.out.println("getShape " + index);
425
                int index = (int) (rowIndex);
426
                try {
427
                        setAbsolutePosition(index);
428
                        int fieldId = idField + 2;
429
                        return getFieldValue(rs, fieldId);
430

    
431
                } catch (SQLException e) {
432
                        // TODO Auto-generated catch block
433
                        throw new com.hardcode.gdbms.engine.data.driver.DriverException(e
434
                                        .getMessage());
435
                }
436
        }
437

    
438
        static Value getFieldValue(ResultSet aRs, int fieldId)
439
        throws SQLException {
440
                ResultSetMetaData metaData = aRs.getMetaData();
441
                byte[] byteBuf = aRs.getBytes(fieldId);
442
                if (byteBuf == null)
443
                        return ValueFactory.createNullValue();
444
                else {
445
                        ByteBuffer buf = ByteBuffer.wrap(byteBuf);
446
                        if (metaData.getColumnType(fieldId) == Types.VARCHAR)
447
                                return ValueFactory.createValue(aRs.getString(fieldId));
448
                        if (metaData.getColumnType(fieldId) == Types.FLOAT)
449
                                return ValueFactory.createValue(buf.getFloat());
450
                        if (metaData.getColumnType(fieldId) == Types.DOUBLE)
451
                                return ValueFactory.createValue(buf.getDouble());
452
                        if (metaData.getColumnType(fieldId) == Types.REAL)
453
                                return ValueFactory.createValue(buf.getFloat());
454
                        if (metaData.getColumnType(fieldId) == Types.INTEGER)
455
                                return ValueFactory.createValue(buf.getInt());
456
                        if (metaData.getColumnType(fieldId) == Types.BIGINT)
457
                                return ValueFactory.createValue(buf.getLong());
458
                        if (metaData.getColumnType(fieldId) == Types.BIT)
459
                                return ValueFactory.createValue((byteBuf[0] == 1));
460
                        if (metaData.getColumnType(fieldId) == Types.BOOLEAN)
461
                                return ValueFactory.createValue(aRs.getBoolean(fieldId));
462
                        if (metaData.getColumnType(fieldId) == Types.DATE)
463
                        {
464
                                long daysAfter2000 = buf.getInt() + 1;
465
                                long msecs = daysAfter2000*24*60*60*1000;
466
                                long real_msecs_date1 = (long) (XTypes.NUM_msSecs2000 + msecs);
467
                                Date realDate1 = new Date(real_msecs_date1);
468
                                return ValueFactory.createValue(realDate1);
469
                        }
470
                        if (metaData.getColumnType(fieldId) == Types.TIME)
471
                        {
472
                                // TODO:
473
                                        // throw new RuntimeException("TIME type not implemented yet");
474
                                return ValueFactory.createValue("NOT IMPLEMENTED YET");
475
                        }
476
                        if (metaData.getColumnType(fieldId) == Types.TIMESTAMP)
477
                        {
478
                                double segsReferredTo2000 = buf.getDouble();
479
                                long real_msecs = (long) (XTypes.NUM_msSecs2000 + segsReferredTo2000*1000);
480
                                Timestamp valTimeStamp = new Timestamp(real_msecs);
481
                                return ValueFactory.createValue(valTimeStamp);
482
                        }
483

    
484
                        if (metaData.getColumnType(fieldId) == Types.NUMERIC) {
485
                                // System.out.println(metaData.getColumnName(fieldId) + " "
486
                                // + metaData.getColumnClassName(fieldId));
487
                                short ndigits = buf.getShort();
488
                                short weight = buf.getShort();
489
                                short sign = buf.getShort();
490
                                short dscale = buf.getShort();
491
                                String strAux;
492
                                if (sign == 0)
493
                                        strAux = "+";
494
                                else
495
                                        strAux = "-";
496

    
497
                                for (int iDigit = 0; iDigit < ndigits; iDigit++) {
498
                                        short digit = buf.getShort();
499
                                        strAux = strAux + digit;
500
                                        if (iDigit == weight)
501
                                                strAux = strAux + ".";
502

    
503
                                }
504
                                strAux = strAux + "0";
505
                                BigDecimal dec;
506
                                dec = new BigDecimal(strAux);
507
                                // System.out.println(ndigits + "_" + weight + "_" + dscale
508
                                // + "_" + strAux);
509
                                // System.out.println(strAux + " Big= " + dec);
510
                                return ValueFactory.createValue(dec.doubleValue());
511
                        }
512

    
513
                }
514
                return ValueFactory.createNullValue();
515

    
516
        }
517

    
518
        public void open() throws com.iver.cit.gvsig.fmap.DriverException {
519
                /*
520
                 * try { st = conn.createStatement(); st.setFetchSize(2000); if
521
                 * (bCursorActivo) close(); st.execute("declare wkb_cursor binary cursor
522
                 * for " + sqlOrig); rs = st.executeQuery("fetch forward all in
523
                 * wkb_cursor"); // st.execute("BEGIN"); bCursorActivo = true; } catch
524
                 * (SQLException e) { e.printStackTrace(); throw new
525
                 * com.iver.cit.gvsig.fmap.DriverException(e); }
526
                 */
527

    
528
        }
529

    
530
        private void setAbsolutePosition(int index) throws SQLException {
531
                // TODO: USAR LIMIT Y ORDER BY, Y HACERLO TAMBI?N PARA
532
                // MYSQL
533

    
534
                // EL ABSOLUTE NO HACE QUE SE VUELVAN A LEER LAS
535
                // FILAS, ASI QUE MONTAMOS ESTA HISTORIA PARA QUE
536
                // LO HAGA
537
                // System.out.println("getShape " + index + " fetchMin=" + fetch_min + "
538
                // fetchMax=" + fetch_max);
539

    
540
                if ((index >= fetch_min) && (index <= fetch_max))
541
                {
542
                        // Est? en el intervalo, as? que lo podemos posicionar
543

    
544
                }
545
                else
546
                {
547
                        // calculamos el intervalo correcto
548
                        fetch_min = (index / FETCH_SIZE) * FETCH_SIZE;
549
                        fetch_max = fetch_min +  FETCH_SIZE - 1;
550
                        // y cogemos ese cacho
551
                        rs.close();
552
                        myCursorId++;
553
                        st.execute("declare " + getTableName() + myCursorId + "_wkb_cursorAbsolutePosition binary scroll cursor with hold for " + sqlTotal);
554
                        st.executeQuery("fetch absolute " + fetch_min
555
                        + " in " + getTableName() + myCursorId + "_wkb_cursorAbsolutePosition");
556

    
557
                        rs = st.executeQuery("fetch forward " + FETCH_SIZE
558
                        + " in " + getTableName() + myCursorId + "_wkb_cursorAbsolutePosition");
559

    
560
                }
561
                rs.absolute(index - fetch_min + 1);
562
                actual_position = index;
563

    
564
        }
565

    
566
        /**
567
         * @see com.iver.cit.gvsig.fmap.drivers.IVectorialDatabaseDriver#getGeometryField(java.lang.String)
568
         */
569
        public String getGeometryField(String fieldName) {
570
                return "ASBINARY(" + fieldName + ", 'XDR')";
571
        }
572

    
573
        /**
574
         * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#getPrimaryKeys()
575
         */
576
        public int[] getPrimaryKeys()
577
                        throws com.hardcode.gdbms.engine.data.driver.DriverException {
578
                // TODO Auto-generated method stub
579
                return null;
580
        }
581

    
582
        /**
583
         * @see com.iver.cit.gvsig.fmap.drivers.IVectorialJDBCDriver#getDefaultPort()
584
         */
585
        public int getDefaultPort() {
586
                return 5432;
587
        }
588

    
589
        /**
590
         * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#write(com.hardcode.gdbms.engine.data.edition.DataWare)
591
         */
592
        public void write(DataWare arg0)
593
                        throws com.hardcode.gdbms.engine.data.driver.DriverException {
594
                // TODO Auto-generated method stub
595

    
596
        }
597

    
598
        /*
599
         * (non-Javadoc)
600
         *
601
         * @see com.iver.cit.gvsig.fmap.core.ICanReproject#getSourceProjection()
602
         */
603
        public String getSourceProjection(IConnection conn,DBLayerDefinition dbld) {
604
                if (originalEPSG == null)
605
                        getTableEPSG_and_shapeType(conn,dbld);
606
                return originalEPSG;
607
        }
608

    
609
        /**
610
         * Las tablas con geometr?as est?n en la tabla GEOMETRY_COLUMNS y de
611
         * ah? sacamos en qu? proyecci?n est?n.
612
         * El problema es que si el usuario hace una vista de esa
613
         * tabla, no estar? dada de alta aqu? y entonces gvSIG
614
         * no se entera en qu? proyecci?n est? trabajando (y le
615
         * ponemos un -1 como mal menor). El -1 implica que luego
616
         * no podremos reproyectar al vuelo desde la base de datos.
617
         * OJO: ES SENSIBLE A MAYUSCULAS / MINUSCULAS!!!
618
         * @param dbld
619
         */
620
        private void getTableEPSG_and_shapeType(IConnection conn, DBLayerDefinition dbld) {
621
                try {
622
                        Statement stAux = ((ConnectionJDBC)conn).getConnection().createStatement();
623

    
624
//                        String sql = "SELECT * FROM GEOMETRY_COLUMNS WHERE F_TABLE_NAME = '"
625
//                                        + getTableName() + "' AND F_GEOMETRY_COLUMN = '" + getLyrDef().getFieldGeometry() + "'";
626
                        String sql;
627
                        if (dbld.getSchema() == null || dbld.getSchema().equals("")){
628
                                sql = "SELECT * FROM GEOMETRY_COLUMNS WHERE F_TABLE_SCHEMA = current_schema() AND F_TABLE_NAME = '"
629
                                        + dbld.getTableName() + "' AND F_GEOMETRY_COLUMN = '" + dbld.getFieldGeometry() + "'";
630
                        }else{
631
                                sql = "SELECT * FROM GEOMETRY_COLUMNS WHERE F_TABLE_SCHEMA = '"+ dbld.getSchema() + "' AND F_TABLE_NAME = '"
632
                                                + dbld.getTableName() + "' AND F_GEOMETRY_COLUMN = '" + dbld.getFieldGeometry() + "'";
633
                        }
634

    
635
                        ResultSet rs = stAux.executeQuery(sql);
636
                        rs.next();
637
                        originalEPSG = "" + rs.getInt("SRID");
638
                        String geometryType = rs.getString("TYPE");
639
                        int shapeType = FShape.MULTI;
640
                        if (geometryType.compareToIgnoreCase("POINT") == 0)
641
                                shapeType = FShape.POINT;
642
                        else if (geometryType.compareToIgnoreCase("LINESTRING") == 0)
643
                                shapeType = FShape.LINE;
644
                        else if (geometryType.compareToIgnoreCase("POLYGON") == 0)
645
                                shapeType = FShape.POLYGON;
646
                        else if (geometryType.compareToIgnoreCase("MULTIPOINT") == 0)
647
                                shapeType = FShape.POINT;
648
                        else if (geometryType.compareToIgnoreCase("MULTILINESTRING") == 0)
649
                                shapeType = FShape.LINE;
650
                        else if (geometryType.compareToIgnoreCase("MULTIPOLYGON") == 0)
651
                                shapeType = FShape.POLYGON;
652

    
653
                        dbld.setShapeType(shapeType);
654
                        rs.close();
655
                } catch (SQLException e) {
656
                        // TODO Auto-generated catch block
657
                        originalEPSG = "-1";
658
                        logger.error(e);
659
                        e.printStackTrace();
660
                }
661

    
662
        }
663

    
664
        /*
665
         * (non-Javadoc)
666
         *
667
         * @see com.iver.cit.gvsig.fmap.core.ICanReproject#getDestProjection()
668
         */
669
        public String getDestProjection() {
670
                return strEPSG;
671
        }
672

    
673
        /*
674
         * (non-Javadoc)
675
         *
676
         * @see com.iver.cit.gvsig.fmap.core.ICanReproject#setDestProjection(java.lang.String)
677
         */
678
        public void setDestProjection(String toEPSG) {
679
                this.strEPSG = toEPSG;
680
        }
681

    
682
        /*
683
         * (non-Javadoc)
684
         *
685
         * @see com.iver.cit.gvsig.fmap.core.ICanReproject#canReproject(java.lang.String)
686
         */
687
        public boolean canReproject(String toEPSGdestinyProjection) {
688
                // TODO POR AHORA, REPROYECTA SIEMPRE gvSIG.
689
                return false;
690
        }
691

    
692
        /*
693
         * (non-Javadoc)
694
         *
695
         * @see com.iver.cit.gvsig.fmap.drivers.DefaultDBDriver#doRelateID_FID()
696
         */
697
        protected void doRelateID_FID() throws DBException {
698
                hashRelate = new Hashtable();
699
                try {
700
                        String strSQL = "SELECT " + getLyrDef().getFieldID() + " FROM "
701
                                        + getLyrDef().getComposedTableName() + " ";
702
                                        // + getLyrDef().getWhereClause();
703
                        if (canReproject(strEPSG)) {
704
                                strSQL = strSQL
705
                                                + getCompoundWhere(strSQL, workingArea, strEPSG);
706
                        } else {
707
                                strSQL = strSQL
708
                                                + getCompoundWhere(strSQL, workingArea, originalEPSG);
709
                        }
710
                        strSQL = strSQL + " ORDER BY " + getLyrDef().getFieldID();
711
                        Statement s = ((ConnectionJDBC)getConnection()).getConnection().createStatement(
712
                                        ResultSet.TYPE_SCROLL_INSENSITIVE,
713
                                        ResultSet.CONCUR_READ_ONLY);
714
                        s.setFetchSize(FETCH_SIZE);
715
                        ResultSet r = s.executeQuery(strSQL);
716
                        int id = 0;
717
                        String gid;
718
                        while (r.next()) {
719
                                gid = r.getString(1);
720
                                Value aux = ValueFactory.createValue(gid);
721
                                hashRelate.put(aux, new Integer(id));
722
//                                 System.out.println("ASOCIANDO CLAVE " + aux + " CON VALOR " + id);
723
                                id++;
724
//                                 System.out.println("Row " + id + ":" + strAux);
725
                        }
726
                        s.close();
727
                        numReg = id;
728

    
729
                        /*
730
                         * for (int index = 0; index < getShapeCount(); index++) { Value aux =
731
                         * getFieldValue(index, idFID_FieldName-2); hashRelate.put(aux, new
732
                         * Integer(index)); // System.out.println("Row " + index + " clave=" +
733
                         * aux); }
734
                         */
735
                        /*
736
                         * int index = 0;
737
                         *
738
                         * while (rs.next()) { Value aux = getFieldValue(index,
739
                         * idFID_FieldName-2); hashRelate.put(aux, new Integer(index));
740
                         * index++; System.out.println("Row " + index + " clave=" + aux); }
741
                         * numReg = index;
742
                         */
743
                        // rs.beforeFirst();
744
                        /*
745
                         * } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) { //
746
                         * TODO Auto-generated catch block e.printStackTrace();
747
                         */
748
                } catch (SQLException e) {
749
                        throw new DBException(e);
750
                }
751
        }
752

    
753
        public String getSqlTotal() {
754
                return sqlTotal;
755
        }
756

    
757
        /**
758
         * @return Returns the completeWhere.
759
         */
760
        public String getCompleteWhere() {
761
                return completeWhere;
762
        }
763

    
764
        /*
765
         * (non-Javadoc)
766
         *
767
         * @see com.iver.cit.gvsig.fmap.drivers.DefaultDBDriver#close()
768
         */
769
        public void close() {
770
                super.close();
771
                /*
772
                 * if (bCursorActivo) { try { // st =
773
                 * conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
774
                 * ResultSet.CONCUR_READ_ONLY); st.execute("CLOSE wkb_cursor_prov"); //
775
                 * st.close(); } catch (SQLException e) { // TODO Auto-generated catch
776
                 * block e.printStackTrace(); } bCursorActivo = false; }
777
                 */
778

    
779
        }
780

    
781
        /*
782
         * (non-Javadoc)
783
         *
784
         * @see com.iver.cit.gvsig.fmap.drivers.VectorialDatabaseDriver#getFeatureIterator(java.awt.geom.Rectangle2D,
785
         *      java.lang.String, java.lang.String[])
786
         */
787
        public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG,
788
                        String[] alphaNumericFieldsNeeded) throws DriverException {
789
                String sqlAux = null;
790
                try {
791
                        if (workingArea != null)
792
                                r = r.createIntersection(workingArea);
793
                        // if (getLyrDef()==null){
794
                        // load();
795
                        // throw new DriverException("Fallo de la conexi?n");
796
                        // }
797
                        String strAux = getGeometryField(getLyrDef().getFieldGeometry());
798

    
799
                        boolean found = false;
800
                        if (alphaNumericFieldsNeeded != null) {
801
                                for (int i = 0; i < alphaNumericFieldsNeeded.length; i++) {
802
                                        strAux = strAux + ", " + alphaNumericFieldsNeeded[i];
803
                                        if (alphaNumericFieldsNeeded[i].equals(getLyrDef()
804
                                                        .getFieldID()))
805
                                                found = true;
806
                                }
807
                        }
808
                        // Nos aseguramos de pedir siempre el campo ID
809
                        if (found == false)
810
                                strAux = strAux + ", " + getLyrDef().getFieldID();
811

    
812
                        String sqlProv = "SELECT " + strAux + " FROM "
813
                                        + getLyrDef().getComposedTableName() + " ";
814
                                        // + getLyrDef().getWhereClause();
815

    
816

    
817
                        if (canReproject(strEPSG)) {
818
                                sqlAux = sqlProv + getCompoundWhere(sqlProv, r, strEPSG);
819
                        } else {
820
                                sqlAux = sqlProv + getCompoundWhere(sqlProv, r, originalEPSG);
821
                        }
822

    
823
                        System.out.println("SqlAux getFeatureIterator = " + sqlAux);
824

    
825
                        return getFeatureIterator(sqlAux);
826
                } catch (Exception e) {
827
                        e.printStackTrace();
828
                        SqlDriveExceptionType type = new SqlDriveExceptionType();
829
            type.setDriverName("PostGIS Driver");
830
            type.setSql(sqlAux);
831
            type.setLayerName(getTableName());
832
            type.setSchema(null);
833
            throw new com.iver.cit.gvsig.fmap.DriverException(e, type);
834

    
835
//                        throw new DriverException(e);
836
                }
837
        }
838

    
839
        /* public void preProcess() throws EditionException {
840
                writer.preProcess();
841
        }
842

843
        public void process(IRowEdited row) throws EditionException {
844
                writer.process(row);
845
        }
846

847
        public void postProcess() throws EditionException {
848
                writer.postProcess();
849
        }
850

851
        public String getCapability(String capability) {
852
                return writer.getCapability(capability);
853
        }
854

855
        public void setCapabilities(Properties capabilities) {
856
                writer.setCapabilities(capabilities);
857
        }
858

859
        public boolean canWriteAttribute(int sqlType) {
860
                return writer.canWriteAttribute(sqlType);
861
        }
862

863
        public boolean canWriteGeometry(int gvSIGgeometryType) {
864
                return writer.canWriteGeometry(gvSIGgeometryType);
865
        }
866

867
        public void initialize(ITableDefinition layerDef) throws EditionException {
868
                writer.setCreateTable(false);
869
                writer.setWriteAll(false);
870
                // Obtenemos el DBLayerDefinition a partir del driver
871

872
                DBLayerDefinition dbLyrDef = getLyrDef();
873

874

875
                writer.initialize(dbLyrDef);
876
        }
877
*/
878
        public boolean isWritable() {
879
                return true;
880
        }
881

    
882
        public IWriter getWriter() {
883
                return writer;
884
        }
885

    
886
        public String[] getGeometryFieldsCandidates(IConnection conn, String table_name) throws DBException {
887
                ArrayList list = new ArrayList();
888
                try{
889
                Statement stAux = ((ConnectionJDBC)conn).getConnection().createStatement();
890
                 String[] tokens = table_name.split("\\u002E", 2);
891
        String sql;
892
        if (tokens.length > 1)
893
        {
894
                sql = "select * from GEOMETRY_COLUMNS WHERE F_TABLE_SCHEMA = '"
895
                 + tokens[0] + "' AND F_TABLE_NAME = '" +
896
            tokens[1] + "'";
897
        }
898
        else
899
        {
900
                sql = "select * from GEOMETRY_COLUMNS" +
901
            " where F_TABLE_SCHEMA = current_schema() AND F_TABLE_NAME = " + "'" + table_name + "'";
902

    
903
        }
904

    
905
//                String sql = "SELECT * FROM GEOMETRY_COLUMNS WHERE F_TABLE_NAME = '"
906
//                                + table_name + "'";
907

    
908
                ResultSet rs = stAux.executeQuery(sql);
909
                while (rs.next())
910
                {
911
                        String geomCol = rs.getString("F_GEOMETRY_COLUMN");
912
                        list.add(geomCol);
913
                }
914
                rs.close(); stAux.close();
915
                } catch (SQLException e) {
916
                        throw new DBException(e);
917
                }
918
                return (String[]) list.toArray(new String[0]);
919
        }
920
//        public String[] getTableFields(IConnection conex, String table) throws DBException {
921
//                try{
922
//                Statement st = ((ConnectionJDBC)conex).getConnection().createStatement();
923
//        // ResultSet rs = dbmd.getTables(catalog, null, dbLayerDefinition.getTable(), null);
924
//                ResultSet rs = st.executeQuery("select * from " + table + " LIMIT 1");
925
//                ResultSetMetaData rsmd = rs.getMetaData();
926
//
927
//                String[] ret = new String[rsmd.getColumnCount()];
928
//
929
//                for (int i = 0; i < ret.length; i++) {
930
//                        ret[i] = rsmd.getColumnName(i+1);
931
//                }
932
//
933
//                return ret;
934
//                }catch (SQLException e) {
935
//                        throw new DBException(e);
936
//                }
937
//        }
938
//        public String[] getTableNames(IConnection conn, String catalog) throws DBException {
939
//                // TODO Auto-generated method stub
940
//                return super.getTableNames(conn, catalog);
941
//        }
942

    
943
}