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 @ 46050

History | View | Annotate | Download (19.5 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 44644 jjdelcerro
import static 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 43093 jjdelcerro
import org.gvsig.fmap.dal.feature.spi.SQLBuilderBase;
43 43020 jjdelcerro
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
44 43479 jjdelcerro
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
45 43687 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
46 45097 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
47 43629 jjdelcerro
import org.gvsig.fmap.geom.Geometry;
48 43687 jjdelcerro
import org.gvsig.fmap.geom.GeometryLocator;
49
import org.gvsig.fmap.geom.GeometryManager;
50
import org.gvsig.fmap.geom.aggregate.MultiLine;
51
import org.gvsig.fmap.geom.aggregate.MultiPoint;
52
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
53
import org.gvsig.fmap.geom.exception.CreateGeometryException;
54
import org.gvsig.fmap.geom.primitive.Primitive;
55
import org.gvsig.fmap.geom.type.GeometryType;
56 45694 fdiaz
import org.gvsig.tools.ToolsLocator;
57
import org.gvsig.tools.dataTypes.DataType;
58
import org.gvsig.tools.dataTypes.DataTypes;
59
import org.gvsig.tools.dataTypes.DataTypesManager;
60 43629 jjdelcerro
import org.gvsig.tools.dispose.Disposable;
61 43020 jjdelcerro
62 44198 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
63 43020 jjdelcerro
public class JDBCSQLBuilderBase extends SQLBuilderBase {
64
65 44198 jjdelcerro
    public static final String PROP_FEATURE_TYPE = "FeatureType";
66
    public static final String PROP_TABLE = "Table";
67 46010 jjdelcerro
    public static final String PROP_SYMBOLTABLE = "SymbolTable";
68
    public static final String PROP_JDBCHELPER = "JDBCHelper";
69 46050 omartinez
    public static final String PROP_QUERY = "Query";
70 44198 jjdelcerro
71 43687 jjdelcerro
    private GeometryManager geometryManager = null;
72
    protected final JDBCHelper helper;
73
74
    public JDBCSQLBuilderBase(JDBCHelper helper) {
75 43020 jjdelcerro
        super();
76 43687 jjdelcerro
        this.helper = helper;
77 43020 jjdelcerro
    }
78 43687 jjdelcerro
79
    public JDBCHelper getHelper() {
80
        return helper;
81
    }
82
83
    protected GeometryManager getGeometryManager() {
84
        if (this.geometryManager == null) {
85
            this.geometryManager = GeometryLocator.getGeometryManager();
86
        }
87
        return this.geometryManager;
88
    }
89
90
    @Override
91 44198 jjdelcerro
    public Object srs_id(IProjection projection) {
92 43687 jjdelcerro
        Connection conn = null;
93
        try {
94
            conn = this.helper.getConnection();
95
            SRSSolver solver = this.helper.getSRSSolver();
96
            Object srscode = solver.getDatabaseCode(conn, projection);
97 43737 jjdelcerro
//            logger.debug("database code srs {}, type {}, srssolver {}.",
98
//                new Object[] {
99
//                    srscode,
100
//                    srscode==null? "null":srscode.getClass().getSimpleName(),
101
//                    solver
102
//                }
103
//            );
104 43687 jjdelcerro
            return srscode;
105
        } catch (Exception ex) {
106
            throw new RuntimeException("Can't locate database code for SRS '"+projection.getAbrev()+"'.");
107
        } finally {
108 44191 jjdelcerro
            this.helper.closeConnectionQuietly(conn);
109 43687 jjdelcerro
        }
110
    }
111
112 43093 jjdelcerro
    public void setParameters(PreparedStatement st) {
113
        try {
114
            int columnIndex = 1;
115 44198 jjdelcerro
            for (Parameter parameter : this.parameters()) {
116
                st.setObject(columnIndex++, parameter.value());
117 43093 jjdelcerro
            }
118
        } catch (Exception ex) {
119
            String p = "unknow";
120
            try {
121 44198 jjdelcerro
                p =  this.parameters().toString();
122 43093 jjdelcerro
            } catch (Exception ex2) {
123
                // Do nothing
124
            }
125
            throw new RuntimeException("Can't set parameters to prepared statement from parameters (" + p + ")", ex);
126
        }
127
    }
128
129 44678 jjdelcerro
    public List<Object> getParameters(FeatureProvider feature) {
130 45694 fdiaz
        return getParameters(feature, null);
131
    }
132
    public List<Object> getParameters(FeatureProvider feature, List<Integer> types) {
133 43020 jjdelcerro
        try {
134 45694 fdiaz
            DataTypesManager dataTypesManager = ToolsLocator.getDataTypesManager();
135 43687 jjdelcerro
            FeatureType type = feature.getType();
136 43020 jjdelcerro
            List<Object> values = new ArrayList<>();
137 43687 jjdelcerro
            Object value;
138 44198 jjdelcerro
            for (Parameter parameter : this.parameters()) {
139 43093 jjdelcerro
                if (parameter.is_constant()) {
140 44198 jjdelcerro
                    value = parameter.value();
141 43687 jjdelcerro
                    values.add(value);
142 45694 fdiaz
                    if(types != null) {
143
                        if (value == null) {
144
                            types.add(org.gvsig.fmap.dal.DataTypes.OBJECT);
145
                        } else {
146
                            DataType dataType = dataTypesManager.getDataType(value.getClass());
147
                            types.add(dataType.getType());
148
                        }
149
                    }
150
151 43020 jjdelcerro
                } else {
152 44198 jjdelcerro
                    String name = parameter.name();
153 43687 jjdelcerro
                    value = feature.get(name);
154
                    FeatureAttributeDescriptor attrDesc = type.getAttributeDescriptor(name);
155 44323 jjdelcerro
                    switch( attrDesc.getType() ) {
156
                    case org.gvsig.fmap.dal.DataTypes.DATE:
157
                        if( value == null ) {
158
                            values.add(null);
159
                        } else {
160
                            values.add(new java.sql.Date(((Date)value).getTime()));
161
                        }
162 45694 fdiaz
                        if (types != null) {
163
                            types.add(org.gvsig.fmap.dal.DataTypes.DATE);
164
                        }
165
166 44323 jjdelcerro
                        break;
167
                    case org.gvsig.fmap.dal.DataTypes.GEOMETRY:
168
                        Geometry geom = this.forceGeometryType(
169
                            attrDesc.getGeomType(),
170
                            (Geometry)value
171
                        );
172
                        values.add(geom);
173 45694 fdiaz
                        if (types != null) {
174
                            types.add(org.gvsig.fmap.dal.DataTypes.GEOMETRY);
175
                        }
176 44323 jjdelcerro
                        break;
177
                    default:
178
                        values.add(value);
179 45694 fdiaz
                        if (types != null) {
180
                            types.add(attrDesc.getDataType().getType());
181
                        }
182
183 44323 jjdelcerro
                        break;
184 43687 jjdelcerro
                    }
185 43020 jjdelcerro
                }
186
            }
187 44678 jjdelcerro
            return  values;
188
        } catch (Exception ex) {
189
            String f = "unknow";
190
            try {
191
                f = feature.toString();
192
            } catch (Exception ex2) {
193
                // Do nothing
194
            }
195
            throw new RuntimeException("Can't get parameters to prepared statement from the feature (" + f + ")", ex);
196
        }
197
    }
198
199
    public Disposable setParameters(PreparedStatement st, FeatureProvider feature) {
200
        try {
201 45694 fdiaz
            List<Integer> types = new ArrayList<>();
202
203
            List<Object> values = this.getParameters(feature, types);
204
            return this.setStatementParameters(st, values, types, this.geometry_support_type());
205 43020 jjdelcerro
        } catch (Exception ex) {
206 43093 jjdelcerro
            String f = "unknow";
207
            try {
208
                f = feature.toString();
209
            } catch (Exception ex2) {
210
                // Do nothing
211
            }
212
            throw new RuntimeException("Can't set parameters to prepared statement from the feature (" + f + ")", ex);
213 43020 jjdelcerro
        }
214
    }
215 43687 jjdelcerro
216
    protected Geometry forceGeometryType(GeometryType geomtype, Geometry geom) throws CreateGeometryException {
217
        if( geom == null ) {
218
            return null;
219
        }
220
        switch( geomtype.getType() ) {
221
        case Geometry.TYPES.MULTIPOLYGON:
222
            if( geom.getType()==Geometry.TYPES.POLYGON ) {
223
                MultiPolygon x = getGeometryManager().createMultiPolygon(geomtype.getSubType());
224
                x.addPrimitive((Primitive) geom);
225
                geom = x;
226
            }
227
            break;
228
        case Geometry.TYPES.MULTILINE:
229
            if( geom.getType()==Geometry.TYPES.LINE ) {
230
                MultiLine x = getGeometryManager().createMultiLine(geomtype.getSubType());
231
                x.addPrimitive((Primitive) geom);
232
                geom = x;
233
            }
234
            break;
235
        case Geometry.TYPES.MULTIPOINT:
236
            if( geom.getType()==Geometry.TYPES.POINT ) {
237
                MultiLine x = getGeometryManager().createMultiLine(geomtype.getSubType());
238
                x.addPrimitive((Primitive) geom);
239
                geom = x;
240
            }
241
            break;
242
        case Geometry.TYPES.POLYGON:
243
            if( geom.getType()==Geometry.TYPES.MULTIPOLYGON ) {
244
                MultiPolygon x = (MultiPolygon) geom;
245
                if( x.getPrimitivesNumber()==1 ) {
246
                    geom = x.getPrimitiveAt(0);
247
                }
248
            }
249
            break;
250
        case Geometry.TYPES.LINE:
251
            if( geom.getType()==Geometry.TYPES.MULTILINE ) {
252
                MultiLine x = (MultiLine) geom;
253
                if( x.getPrimitivesNumber()==1 ) {
254
                    geom = x.getPrimitiveAt(0);
255
                }
256
            }
257
            break;
258
        case Geometry.TYPES.POINT:
259
            if( geom.getType()==Geometry.TYPES.MULTIPOINT ) {
260
                MultiPoint x = (MultiPoint) geom;
261
                if( x.getPrimitivesNumber()==1 ) {
262
                    geom = x.getPrimitiveAt(0);
263
                }
264
            }
265
        }
266
        return geom;
267
    }
268
269 43629 jjdelcerro
    public Disposable setParameters(PreparedStatement st, FeatureReference reference) {
270 43479 jjdelcerro
        try {
271
272
            List<Object> values = new ArrayList<>();
273 44198 jjdelcerro
            for (Parameter parameter : this.parameters()) {
274 43479 jjdelcerro
                if (parameter.is_constant()) {
275 44198 jjdelcerro
                    values.add(parameter.value());
276 43479 jjdelcerro
                } else {
277 44198 jjdelcerro
                    String name = parameter.name();
278 43479 jjdelcerro
                    values.add(((FeatureReferenceProviderServices)reference).getKeyValue(name));
279
                }
280
            }
281 45694 fdiaz
            return this.setStatementParameters(st, values, null, this.geometry_support_type());
282 43479 jjdelcerro
        } catch (Exception ex) {
283
            String f = "unknow";
284
            try {
285
                f = reference.toString();
286
            } catch (Exception ex2) {
287
                // Do nothing
288
            }
289
            throw new RuntimeException("Can't set parameters to prepared statement from the feature (" + f + ")", ex);
290
        }
291
    }
292
293 43629 jjdelcerro
    public Disposable setStatementParameters(
294
        PreparedStatement st,
295 44944 omartinez
        List values,
296 43629 jjdelcerro
        GeometrySupportType geometrySupportType) throws SQLException {
297
298 45694 fdiaz
        return setStatementParameters(st, values, null, geometrySupportType);
299
    }
300
301
    public Disposable setStatementParameters(
302
        PreparedStatement st,
303
        List values,
304
        List<Integer> types, //Can be null
305
        GeometrySupportType geometrySupportType) throws SQLException {
306
307 43629 jjdelcerro
        if (values == null) {
308
            return new Disposable() {
309
                @Override
310
                public void dispose() {
311
                }
312
            };
313
        }
314 44198 jjdelcerro
        if( LOGGER.isDebugEnabled() ) {
315 43732 jjdelcerro
            StringBuilder debug = new StringBuilder();
316 45097 jjdelcerro
            debug.append("[");
317
            debug.append(JDBCUtils.getConnId(st));
318
            debug.append("] st.set(");
319 43732 jjdelcerro
            try {
320
                byte[] bytes;
321
                int columnIndex = 1;
322
                for (Object value : values) {
323
                    if (value instanceof Geometry) {
324
                        switch(geometrySupportType) {
325
                            case WKT:
326
                                value = ((Geometry) value).convertToWKT();
327
                                debug.append("/*");
328
                                debug.append(columnIndex);
329
                                debug.append("*/ ");
330 44198 jjdelcerro
                                debug.append(as_string(value));
331 43732 jjdelcerro
                                debug.append(", ");
332
                                break;
333
                            case NATIVE:
334
                            case WKB:
335
                                bytes = ((Geometry) value).convertToWKB();
336
                                debug.append("/*");
337
                                debug.append(columnIndex);
338
                                debug.append("*/ ");
339 44198 jjdelcerro
                                debug.append(as_string(bytes));
340 43732 jjdelcerro
                                debug.append(", ");
341
                                break;
342
                            case EWKB:
343
                                bytes = ((Geometry) value).convertToEWKB();
344
                                debug.append("/*");
345
                                debug.append(columnIndex);
346
                                debug.append("*/ ");
347 44198 jjdelcerro
                                debug.append(as_string(bytes));
348 43732 jjdelcerro
                                debug.append(", ");
349
                                break;
350
                        }
351
                    } else {
352
                        debug.append("/*");
353
                        debug.append(columnIndex);
354
                        debug.append("*/ ");
355
                        if( value instanceof String ) {
356 44198 jjdelcerro
                            debug.append(as_string(value));
357 43732 jjdelcerro
                        } else if( value instanceof Boolean ) {
358 44198 jjdelcerro
                            debug.append( ((Boolean)value)? constant_true:constant_false );
359 43732 jjdelcerro
                        } else {
360
                            debug.append(value);
361
                        }
362
                        debug.append(", ");
363
                    }
364
                    columnIndex++;
365
                }
366
                debug.append(")");
367 44198 jjdelcerro
                LOGGER.debug(debug.toString());
368 43732 jjdelcerro
            } catch(Exception ex) {
369
            }
370
        }
371 44944 omartinez
        byte[] bytes;
372
        int columnIndex = 1;
373 43629 jjdelcerro
        try {
374
            for (Object value : values) {
375
                if (value instanceof Geometry) {
376
                    switch(geometrySupportType) {
377
                        case WKT:
378
                            value = ((Geometry) value).convertToWKT();
379
                            st.setObject(columnIndex, value);
380
                            break;
381
                        case NATIVE:
382
                        case WKB:
383
                            bytes = ((Geometry) value).convertToWKB();
384
                            st.setBytes(columnIndex, bytes);
385
                            break;
386
                        case EWKB:
387
                            bytes = ((Geometry) value).convertToEWKB();
388
                            st.setBytes(columnIndex, bytes);
389
                            break;
390
                    }
391
                } else {
392 45694 fdiaz
                    if(types == null){
393 44944 omartinez
                        st.setObject(columnIndex, value);
394 45694 fdiaz
                    } else {
395
                        setStatementValue(st, columnIndex, types.get(columnIndex-1), value);
396 44944 omartinez
                    }
397 45694 fdiaz
398
                }
399 43629 jjdelcerro
                columnIndex++;
400
            }
401
            return new Disposable() {
402
                @Override
403
                public void dispose() {
404
                }
405
            };
406
        } catch(Exception ex) {
407
            throw new SQLException("Can't set values for the prepared statement.", ex);
408
        }
409
    }
410 45694 fdiaz
411
    protected void setStatementValue(PreparedStatement st, int columnIndex, int type, Object value) throws SQLException {
412
        switch (type){
413
            case DataTypes.BOOLEAN:
414
                if(value == null){
415
                    st.setNull(columnIndex, java.sql.Types.BIT);
416
                } else {
417
                    st.setBoolean(columnIndex, (boolean) value);
418
                }
419
                break;
420
            case DataTypes.INTEGER:
421
                if(value == null){
422
                    st.setNull(columnIndex, java.sql.Types.INTEGER);
423
                } else {
424
                    st.setInt(columnIndex, (int) value);
425
                }
426
                break;
427
            case DataTypes.BYTE:
428
                if(value == null){
429
                    st.setNull(columnIndex, java.sql.Types.TINYINT);
430
                } else {
431
                    st.setByte(columnIndex, (byte) value);
432
                }
433
                break;
434
            case DataTypes.LONG:
435
                if(value == null){
436
                    st.setNull(columnIndex, java.sql.Types.BIGINT);
437
                } else {
438
                    st.setLong(columnIndex, (long) value);
439
                }
440
                break;
441
            case DataTypes.FLOAT:
442
                if(value == null){
443
                    st.setNull(columnIndex, java.sql.Types.REAL);
444
                } else {
445
                    st.setFloat(columnIndex, (float) value);
446
                }
447
                break;
448
            case DataTypes.DOUBLE:
449
                if(value == null){
450
                    st.setNull(columnIndex, java.sql.Types.DOUBLE);
451
                } else {
452
                    st.setDouble(columnIndex, (double) value);
453
                }
454
                break;
455
            case DataTypes.DECIMAL:
456
                if(value == null){
457
                    st.setNull(columnIndex, java.sql.Types.DECIMAL);
458
                } else {
459
                    st.setBigDecimal(columnIndex, (BigDecimal) value);
460
                }
461
                break;
462 45750 omartinez
            case DataTypes.URL:
463
            case DataTypes.URI:
464
            case DataTypes.FILE:
465
                value = Objects.toString(value, null);
466 45694 fdiaz
            case DataTypes.STRING:
467
                if(value == null){
468
                    st.setNull(columnIndex, java.sql.Types.VARCHAR);
469
                } else {
470
                    st.setString(columnIndex, (String) value);
471
                }
472
                break;
473
            case DataTypes.TIMESTAMP:
474
                if(value == null){
475
                    st.setNull(columnIndex, java.sql.Types.TIMESTAMP);
476
                } else {
477
                    st.setTimestamp(columnIndex, (Timestamp) value);
478
                }
479
                break;
480
            case DataTypes.TIME:
481
                if(value == null){
482
                    st.setNull(columnIndex, java.sql.Types.TIME);
483
                } else {
484
                    st.setTime(columnIndex, (Time) value);
485
                }
486
                break;
487
            case DataTypes.DATE:
488
                if(value == null){
489
                    st.setNull(columnIndex, java.sql.Types.DATE);
490
                } else {
491
                    st.setDate(columnIndex, (java.sql.Date)value);
492
                }
493
                break;
494
            case DataTypes.BYTEARRAY:
495
                if(value == null){
496
                    st.setNull(columnIndex, java.sql.Types.BINARY);
497
                } else {
498
                    st.setBytes(columnIndex, (byte[]) value);
499
                }
500
                break;
501
            default:
502
                st.setObject(columnIndex, value);
503
                LOGGER.debug("Attention, using a statement.setObject");
504
        }
505
    }
506 43020 jjdelcerro
}