Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.db / org.gvsig.fmap.dal.db.jdbc / src / main / java / org / gvsig / fmap / dal / store / jdbc2 / spi / JDBCSQLBuilderBase.java @ 47787

History | View | Annotate | Download (19.7 KB)

1 45065 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2020 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24 43020 jjdelcerro
package org.gvsig.fmap.dal.store.jdbc2.spi;
25
26 45694 fdiaz
import java.math.BigDecimal;
27 43687 jjdelcerro
import java.sql.Connection;
28 43020 jjdelcerro
import java.sql.PreparedStatement;
29 43629 jjdelcerro
import java.sql.SQLException;
30 45694 fdiaz
import java.sql.Time;
31
import java.sql.Timestamp;
32 43020 jjdelcerro
import java.util.ArrayList;
33 44323 jjdelcerro
import java.util.Date;
34 43020 jjdelcerro
import java.util.List;
35 45750 omartinez
import java.util.Objects;
36 43687 jjdelcerro
import org.cresques.cts.IProjection;
37 44198 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionBuilder.Parameter;
38 47574 fdiaz
import org.gvsig.expressionevaluator.GeometryExpressionBuilderHelper.GeometrySupportType;
39 43687 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
40 43479 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureReference;
41 43687 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureType;
42 43020 jjdelcerro
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
43 43479 jjdelcerro
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
44 47574 fdiaz
import org.gvsig.fmap.dal.feature.spi.SQLBuilderBase;
45 46315 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc2.JDBCConnection;
46 43687 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
47 45097 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
48 43629 jjdelcerro
import org.gvsig.fmap.geom.Geometry;
49 43687 jjdelcerro
import org.gvsig.fmap.geom.GeometryLocator;
50
import org.gvsig.fmap.geom.GeometryManager;
51
import org.gvsig.fmap.geom.aggregate.MultiLine;
52
import org.gvsig.fmap.geom.aggregate.MultiPoint;
53
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
54
import org.gvsig.fmap.geom.exception.CreateGeometryException;
55
import org.gvsig.fmap.geom.primitive.Primitive;
56
import org.gvsig.fmap.geom.type.GeometryType;
57 45694 fdiaz
import org.gvsig.tools.ToolsLocator;
58
import org.gvsig.tools.dataTypes.DataType;
59
import org.gvsig.tools.dataTypes.DataTypes;
60
import org.gvsig.tools.dataTypes.DataTypesManager;
61 43629 jjdelcerro
import org.gvsig.tools.dispose.Disposable;
62 43020 jjdelcerro
63 44198 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
64 43020 jjdelcerro
public class JDBCSQLBuilderBase extends SQLBuilderBase {
65
66 43687 jjdelcerro
    private GeometryManager geometryManager = null;
67
    protected final JDBCHelper helper;
68
69
    public JDBCSQLBuilderBase(JDBCHelper helper) {
70 43020 jjdelcerro
        super();
71 43687 jjdelcerro
        this.helper = helper;
72 43020 jjdelcerro
    }
73 43687 jjdelcerro
74
    public JDBCHelper getHelper() {
75
        return helper;
76
    }
77
78
    protected GeometryManager getGeometryManager() {
79
        if (this.geometryManager == null) {
80
            this.geometryManager = GeometryLocator.getGeometryManager();
81
        }
82
        return this.geometryManager;
83
    }
84
85
    @Override
86 44198 jjdelcerro
    public Object srs_id(IProjection projection) {
87 46315 jjdelcerro
        JDBCConnection conn = null;
88 43687 jjdelcerro
        try {
89
            conn = this.helper.getConnection();
90
            SRSSolver solver = this.helper.getSRSSolver();
91
            Object srscode = solver.getDatabaseCode(conn, projection);
92 43737 jjdelcerro
//            logger.debug("database code srs {}, type {}, srssolver {}.",
93
//                new Object[] {
94
//                    srscode,
95
//                    srscode==null? "null":srscode.getClass().getSimpleName(),
96
//                    solver
97
//                }
98
//            );
99 43687 jjdelcerro
            return srscode;
100
        } catch (Exception ex) {
101 47541 jjdelcerro
            throw new RuntimeException("Can't locate database code for SRS '"+projection.getAbrev()+"'.", ex);
102 43687 jjdelcerro
        } finally {
103 46315 jjdelcerro
            conn.closeQuietly();
104 43687 jjdelcerro
        }
105
    }
106
107 43093 jjdelcerro
    public void setParameters(PreparedStatement st) {
108
        try {
109
            int columnIndex = 1;
110 44198 jjdelcerro
            for (Parameter parameter : this.parameters()) {
111
                st.setObject(columnIndex++, parameter.value());
112 43093 jjdelcerro
            }
113
        } catch (Exception ex) {
114
            String p = "unknow";
115
            try {
116 44198 jjdelcerro
                p =  this.parameters().toString();
117 43093 jjdelcerro
            } catch (Exception ex2) {
118
                // Do nothing
119
            }
120
            throw new RuntimeException("Can't set parameters to prepared statement from parameters (" + p + ")", ex);
121
        }
122
    }
123
124 44678 jjdelcerro
    public List<Object> getParameters(FeatureProvider feature) {
125 45694 fdiaz
        return getParameters(feature, null);
126
    }
127
    public List<Object> getParameters(FeatureProvider feature, List<Integer> types) {
128 43020 jjdelcerro
        try {
129 45694 fdiaz
            DataTypesManager dataTypesManager = ToolsLocator.getDataTypesManager();
130 43687 jjdelcerro
            FeatureType type = feature.getType();
131 43020 jjdelcerro
            List<Object> values = new ArrayList<>();
132 43687 jjdelcerro
            Object value;
133 44198 jjdelcerro
            for (Parameter parameter : this.parameters()) {
134 43093 jjdelcerro
                if (parameter.is_constant()) {
135 44198 jjdelcerro
                    value = parameter.value();
136 43687 jjdelcerro
                    values.add(value);
137 45694 fdiaz
                    if(types != null) {
138
                        if (value == null) {
139
                            types.add(org.gvsig.fmap.dal.DataTypes.OBJECT);
140
                        } else {
141
                            DataType dataType = dataTypesManager.getDataType(value.getClass());
142
                            types.add(dataType.getType());
143
                        }
144
                    }
145
146 43020 jjdelcerro
                } else {
147 44198 jjdelcerro
                    String name = parameter.name();
148 43687 jjdelcerro
                    value = feature.get(name);
149
                    FeatureAttributeDescriptor attrDesc = type.getAttributeDescriptor(name);
150 44323 jjdelcerro
                    switch( attrDesc.getType() ) {
151
                    case org.gvsig.fmap.dal.DataTypes.DATE:
152
                        if( value == null ) {
153
                            values.add(null);
154
                        } else {
155
                            values.add(new java.sql.Date(((Date)value).getTime()));
156
                        }
157 45694 fdiaz
                        if (types != null) {
158
                            types.add(org.gvsig.fmap.dal.DataTypes.DATE);
159
                        }
160
161 44323 jjdelcerro
                        break;
162
                    case org.gvsig.fmap.dal.DataTypes.GEOMETRY:
163
                        Geometry geom = this.forceGeometryType(
164
                            attrDesc.getGeomType(),
165
                            (Geometry)value
166
                        );
167
                        values.add(geom);
168 45694 fdiaz
                        if (types != null) {
169
                            types.add(org.gvsig.fmap.dal.DataTypes.GEOMETRY);
170
                        }
171 44323 jjdelcerro
                        break;
172
                    default:
173
                        values.add(value);
174 45694 fdiaz
                        if (types != null) {
175
                            types.add(attrDesc.getDataType().getType());
176
                        }
177
178 44323 jjdelcerro
                        break;
179 43687 jjdelcerro
                    }
180 43020 jjdelcerro
                }
181
            }
182 44678 jjdelcerro
            return  values;
183
        } catch (Exception ex) {
184
            String f = "unknow";
185
            try {
186
                f = feature.toString();
187
            } catch (Exception ex2) {
188
                // Do nothing
189
            }
190
            throw new RuntimeException("Can't get parameters to prepared statement from the feature (" + f + ")", ex);
191
        }
192
    }
193
194
    public Disposable setParameters(PreparedStatement st, FeatureProvider feature) {
195
        try {
196 45694 fdiaz
            List<Integer> types = new ArrayList<>();
197
198
            List<Object> values = this.getParameters(feature, types);
199
            return this.setStatementParameters(st, values, types, this.geometry_support_type());
200 43020 jjdelcerro
        } catch (Exception ex) {
201 43093 jjdelcerro
            String f = "unknow";
202
            try {
203
                f = feature.toString();
204
            } catch (Exception ex2) {
205
                // Do nothing
206
            }
207
            throw new RuntimeException("Can't set parameters to prepared statement from the feature (" + f + ")", ex);
208 43020 jjdelcerro
        }
209
    }
210 43687 jjdelcerro
211
    protected Geometry forceGeometryType(GeometryType geomtype, Geometry geom) throws CreateGeometryException {
212
        if( geom == null ) {
213
            return null;
214
        }
215
        switch( geomtype.getType() ) {
216
        case Geometry.TYPES.MULTIPOLYGON:
217
            if( geom.getType()==Geometry.TYPES.POLYGON ) {
218
                MultiPolygon x = getGeometryManager().createMultiPolygon(geomtype.getSubType());
219
                x.addPrimitive((Primitive) geom);
220
                geom = x;
221
            }
222
            break;
223
        case Geometry.TYPES.MULTILINE:
224
            if( geom.getType()==Geometry.TYPES.LINE ) {
225
                MultiLine x = getGeometryManager().createMultiLine(geomtype.getSubType());
226
                x.addPrimitive((Primitive) geom);
227
                geom = x;
228
            }
229
            break;
230
        case Geometry.TYPES.MULTIPOINT:
231
            if( geom.getType()==Geometry.TYPES.POINT ) {
232
                MultiLine x = getGeometryManager().createMultiLine(geomtype.getSubType());
233
                x.addPrimitive((Primitive) geom);
234
                geom = x;
235
            }
236
            break;
237
        case Geometry.TYPES.POLYGON:
238
            if( geom.getType()==Geometry.TYPES.MULTIPOLYGON ) {
239
                MultiPolygon x = (MultiPolygon) geom;
240
                if( x.getPrimitivesNumber()==1 ) {
241
                    geom = x.getPrimitiveAt(0);
242
                }
243
            }
244
            break;
245
        case Geometry.TYPES.LINE:
246
            if( geom.getType()==Geometry.TYPES.MULTILINE ) {
247
                MultiLine x = (MultiLine) geom;
248
                if( x.getPrimitivesNumber()==1 ) {
249
                    geom = x.getPrimitiveAt(0);
250
                }
251
            }
252
            break;
253
        case Geometry.TYPES.POINT:
254
            if( geom.getType()==Geometry.TYPES.MULTIPOINT ) {
255
                MultiPoint x = (MultiPoint) geom;
256
                if( x.getPrimitivesNumber()==1 ) {
257
                    geom = x.getPrimitiveAt(0);
258
                }
259
            }
260
        }
261
        return geom;
262
    }
263
264 43629 jjdelcerro
    public Disposable setParameters(PreparedStatement st, FeatureReference reference) {
265 43479 jjdelcerro
        try {
266
267
            List<Object> values = new ArrayList<>();
268 44198 jjdelcerro
            for (Parameter parameter : this.parameters()) {
269 43479 jjdelcerro
                if (parameter.is_constant()) {
270 44198 jjdelcerro
                    values.add(parameter.value());
271 43479 jjdelcerro
                } else {
272 44198 jjdelcerro
                    String name = parameter.name();
273 43479 jjdelcerro
                    values.add(((FeatureReferenceProviderServices)reference).getKeyValue(name));
274
                }
275
            }
276 45694 fdiaz
            return this.setStatementParameters(st, values, null, this.geometry_support_type());
277 43479 jjdelcerro
        } catch (Exception ex) {
278
            String f = "unknow";
279
            try {
280
                f = reference.toString();
281
            } catch (Exception ex2) {
282
                // Do nothing
283
            }
284
            throw new RuntimeException("Can't set parameters to prepared statement from the feature (" + f + ")", ex);
285
        }
286
    }
287
288 43629 jjdelcerro
    public Disposable setStatementParameters(
289
        PreparedStatement st,
290 44944 omartinez
        List values,
291 43629 jjdelcerro
        GeometrySupportType geometrySupportType) throws SQLException {
292
293 45694 fdiaz
        return setStatementParameters(st, values, null, geometrySupportType);
294
    }
295
296
    public Disposable setStatementParameters(
297
        PreparedStatement st,
298
        List values,
299
        List<Integer> types, //Can be null
300
        GeometrySupportType geometrySupportType) throws SQLException {
301
302 43629 jjdelcerro
        if (values == null) {
303
            return new Disposable() {
304
                @Override
305
                public void dispose() {
306
                }
307
            };
308
        }
309 44198 jjdelcerro
        if( LOGGER.isDebugEnabled() ) {
310 46271 jjdelcerro
            debug_setStatementParameters(st, values, types, geometrySupportType);
311 43732 jjdelcerro
        }
312 44944 omartinez
        byte[] bytes;
313
        int columnIndex = 1;
314 43629 jjdelcerro
        try {
315
            for (Object value : values) {
316
                if (value instanceof Geometry) {
317
                    switch(geometrySupportType) {
318
                        case WKT:
319
                            value = ((Geometry) value).convertToWKT();
320
                            st.setObject(columnIndex, value);
321
                            break;
322
                        case NATIVE:
323 47574 fdiaz
                            bytes = getNativeBytes(st.getConnection(),(Geometry) value);
324
                            st.setBytes(columnIndex, bytes);
325
                            break;
326 43629 jjdelcerro
                        case WKB:
327
                            bytes = ((Geometry) value).convertToWKB();
328
                            st.setBytes(columnIndex, bytes);
329
                            break;
330
                        case EWKB:
331
                            bytes = ((Geometry) value).convertToEWKB();
332
                            st.setBytes(columnIndex, bytes);
333
                            break;
334
                    }
335
                } else {
336 45694 fdiaz
                    if(types == null){
337 44944 omartinez
                        st.setObject(columnIndex, value);
338 45694 fdiaz
                    } else {
339
                        setStatementValue(st, columnIndex, types.get(columnIndex-1), value);
340 44944 omartinez
                    }
341 45694 fdiaz
342
                }
343 43629 jjdelcerro
                columnIndex++;
344
            }
345
            return new Disposable() {
346
                @Override
347
                public void dispose() {
348
                }
349
            };
350
        } catch(Exception ex) {
351
            throw new SQLException("Can't set values for the prepared statement.", ex);
352
        }
353
    }
354 47574 fdiaz
355
    protected byte[] getNativeBytes(Connection conn, Geometry geometry) throws Exception {
356
        byte[] bytes = geometry.convertToWKB();
357
        return bytes;
358
    }
359 45694 fdiaz
360 46271 jjdelcerro
    protected void debug_setStatementParameters(
361
        PreparedStatement st,
362
        List values,
363
        List<Integer> types, //Can be null
364
        GeometrySupportType geometrySupportType) throws SQLException {
365
366
        StringBuilder debug = new StringBuilder();
367
        debug.append("[");
368
        debug.append(JDBCUtils.getConnId(st));
369
        debug.append("] st.set(");
370
        try {
371
            byte[] bytes;
372
            int columnIndex = 1;
373
            for (Object value : values) {
374
                if (value instanceof Geometry) {
375
                    switch(geometrySupportType) {
376
                        case WKT:
377
                            value = ((Geometry) value).convertToWKT();
378
                            debug.append("/*");
379
                            debug.append(columnIndex);
380
                            debug.append("*/ ");
381
                            debug.append(as_string(value));
382
                            debug.append(", ");
383
                            break;
384
                        case NATIVE:
385
                        case WKB:
386
                            bytes = ((Geometry) value).convertToWKB();
387
                            debug.append("/*");
388
                            debug.append(columnIndex);
389
                            debug.append("*/ ");
390
                            debug.append(as_string(bytes));
391
                            debug.append(", ");
392
                            break;
393
                        case EWKB:
394
                            bytes = ((Geometry) value).convertToEWKB();
395
                            debug.append("/*");
396
                            debug.append(columnIndex);
397
                            debug.append("*/ ");
398
                            debug.append(as_string(bytes));
399
                            debug.append(", ");
400
                            break;
401
                    }
402
                } else {
403
                    debug.append("/*");
404
                    debug.append(columnIndex);
405
                    debug.append("*/ ");
406
                    if( value instanceof String ) {
407
                        debug.append(as_string(value));
408
                    } else if( value instanceof Boolean ) {
409
                        debug.append( ((Boolean)value)? constant_true:constant_false );
410
                    } else {
411
                        debug.append(value);
412
                    }
413
                    debug.append(", ");
414
                }
415
                columnIndex++;
416
            }
417
            debug.append(")");
418
            LOGGER.debug(debug.toString());
419
        } catch(Exception ex) {
420
        }
421
    }
422
423 45694 fdiaz
    protected void setStatementValue(PreparedStatement st, int columnIndex, int type, Object value) throws SQLException {
424
        switch (type){
425
            case DataTypes.BOOLEAN:
426
                if(value == null){
427
                    st.setNull(columnIndex, java.sql.Types.BIT);
428
                } else {
429
                    st.setBoolean(columnIndex, (boolean) value);
430
                }
431
                break;
432
            case DataTypes.INTEGER:
433
                if(value == null){
434
                    st.setNull(columnIndex, java.sql.Types.INTEGER);
435
                } else {
436
                    st.setInt(columnIndex, (int) value);
437
                }
438
                break;
439
            case DataTypes.BYTE:
440
                if(value == null){
441
                    st.setNull(columnIndex, java.sql.Types.TINYINT);
442
                } else {
443
                    st.setByte(columnIndex, (byte) value);
444
                }
445
                break;
446
            case DataTypes.LONG:
447
                if(value == null){
448
                    st.setNull(columnIndex, java.sql.Types.BIGINT);
449
                } else {
450
                    st.setLong(columnIndex, (long) value);
451
                }
452
                break;
453
            case DataTypes.FLOAT:
454
                if(value == null){
455
                    st.setNull(columnIndex, java.sql.Types.REAL);
456
                } else {
457
                    st.setFloat(columnIndex, (float) value);
458
                }
459
                break;
460
            case DataTypes.DOUBLE:
461
                if(value == null){
462
                    st.setNull(columnIndex, java.sql.Types.DOUBLE);
463
                } else {
464
                    st.setDouble(columnIndex, (double) value);
465
                }
466
                break;
467
            case DataTypes.DECIMAL:
468
                if(value == null){
469
                    st.setNull(columnIndex, java.sql.Types.DECIMAL);
470
                } else {
471
                    st.setBigDecimal(columnIndex, (BigDecimal) value);
472
                }
473
                break;
474 45750 omartinez
            case DataTypes.URL:
475
            case DataTypes.URI:
476
            case DataTypes.FILE:
477
                value = Objects.toString(value, null);
478 45694 fdiaz
            case DataTypes.STRING:
479
                if(value == null){
480
                    st.setNull(columnIndex, java.sql.Types.VARCHAR);
481
                } else {
482
                    st.setString(columnIndex, (String) value);
483
                }
484
                break;
485
            case DataTypes.TIMESTAMP:
486
                if(value == null){
487
                    st.setNull(columnIndex, java.sql.Types.TIMESTAMP);
488
                } else {
489
                    st.setTimestamp(columnIndex, (Timestamp) value);
490
                }
491
                break;
492
            case DataTypes.TIME:
493
                if(value == null){
494
                    st.setNull(columnIndex, java.sql.Types.TIME);
495
                } else {
496
                    st.setTime(columnIndex, (Time) value);
497
                }
498
                break;
499
            case DataTypes.DATE:
500
                if(value == null){
501
                    st.setNull(columnIndex, java.sql.Types.DATE);
502
                } else {
503
                    st.setDate(columnIndex, (java.sql.Date)value);
504
                }
505
                break;
506
            case DataTypes.BYTEARRAY:
507
                if(value == null){
508
                    st.setNull(columnIndex, java.sql.Types.BINARY);
509
                } else {
510
                    st.setBytes(columnIndex, (byte[]) value);
511
                }
512
                break;
513
            default:
514
                st.setObject(columnIndex, value);
515
                LOGGER.debug("Attention, using a statement.setObject");
516
        }
517
    }
518 43020 jjdelcerro
}