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

History | View | Annotate | Download (13.8 KB)

1
/**
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
package org.gvsig.fmap.dal.store.jdbc2.spi;
25

    
26
import java.sql.Connection;
27
import java.sql.PreparedStatement;
28
import java.sql.SQLException;
29
import java.util.ArrayList;
30
import java.util.Date;
31
import java.util.List;
32
import org.cresques.cts.IProjection;
33
import org.gvsig.expressionevaluator.ExpressionBuilder.Parameter;
34
import static org.gvsig.expressionevaluator.GeometryExpressionBuilderHelper.GeometrySupportType;
35
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
36
import org.gvsig.fmap.dal.feature.FeatureReference;
37
import org.gvsig.fmap.dal.feature.FeatureType;
38
import org.gvsig.fmap.dal.feature.spi.SQLBuilderBase;
39
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
40
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
41
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
42
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
43
import org.gvsig.fmap.geom.Geometry;
44
import org.gvsig.fmap.geom.GeometryLocator;
45
import org.gvsig.fmap.geom.GeometryManager;
46
import org.gvsig.fmap.geom.aggregate.MultiLine;
47
import org.gvsig.fmap.geom.aggregate.MultiPoint;
48
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
49
import org.gvsig.fmap.geom.exception.CreateGeometryException;
50
import org.gvsig.fmap.geom.primitive.Primitive;
51
import org.gvsig.fmap.geom.type.GeometryType;
52
import org.gvsig.tools.dispose.Disposable;
53

    
54
@SuppressWarnings("UseSpecificCatch")
55
public class JDBCSQLBuilderBase extends SQLBuilderBase {
56

    
57
    public static final String PROP_FEATURE_TYPE = "FeatureType";
58
    public static final String PROP_TABLE = "Table";
59
    
60
    private GeometryManager geometryManager = null;
61
    protected final JDBCHelper helper;
62
    
63
    public JDBCSQLBuilderBase(JDBCHelper helper) {
64
        super();
65
        this.helper = helper;
66
    }
67
    
68
    public JDBCHelper getHelper() {
69
        return helper;
70
    }
71
    
72
    protected GeometryManager getGeometryManager() {
73
        if (this.geometryManager == null) {
74
            this.geometryManager = GeometryLocator.getGeometryManager();
75
        }
76
        return this.geometryManager;
77
    }
78
    
79
    @Override
80
    public Object srs_id(IProjection projection) {
81
        Connection conn = null;
82
        try {
83
            conn = this.helper.getConnection();
84
            SRSSolver solver = this.helper.getSRSSolver();
85
            Object srscode = solver.getDatabaseCode(conn, projection);
86
//            logger.debug("database code srs {}, type {}, srssolver {}.", 
87
//                new Object[] { 
88
//                    srscode, 
89
//                    srscode==null? "null":srscode.getClass().getSimpleName(), 
90
//                    solver
91
//                }
92
//            );
93
            return srscode;
94
        } catch (Exception ex) {
95
            throw new RuntimeException("Can't locate database code for SRS '"+projection.getAbrev()+"'.");
96
        } finally {
97
            this.helper.closeConnectionQuietly(conn);
98
        }
99
    }
100
    
101
    public void setParameters(PreparedStatement st) {
102
        try {
103
            int columnIndex = 1;
104
            for (Parameter parameter : this.parameters()) {
105
                st.setObject(columnIndex++, parameter.value());
106
            }
107
        } catch (Exception ex) {
108
            String p = "unknow";
109
            try {
110
                p =  this.parameters().toString();
111
            } catch (Exception ex2) {
112
                // Do nothing
113
            }
114
            throw new RuntimeException("Can't set parameters to prepared statement from parameters (" + p + ")", ex);
115
        }
116
    }
117

    
118
    public List<Object> getParameters(FeatureProvider feature) {
119
        try {
120
            FeatureType type = feature.getType();
121
            List<Object> values = new ArrayList<>();
122
            Object value;
123
            for (Parameter parameter : this.parameters()) {
124
                if (parameter.is_constant()) {
125
                    value = parameter.value();
126
                    values.add(value);
127
                } else {
128
                    String name = parameter.name();
129
                    value = feature.get(name);
130
                    FeatureAttributeDescriptor attrDesc = type.getAttributeDescriptor(name);
131
                    switch( attrDesc.getType() ) {
132
                    case org.gvsig.fmap.dal.DataTypes.DATE:
133
                        if( value == null ) {
134
                            values.add(null);
135
                        } else {
136
                            values.add(new java.sql.Date(((Date)value).getTime()));
137
                        }
138
                        break;
139
                    case org.gvsig.fmap.dal.DataTypes.GEOMETRY:
140
                        Geometry geom = this.forceGeometryType(
141
                            attrDesc.getGeomType(),
142
                            (Geometry)value
143
                        );
144
                        values.add(geom);
145
                        break;
146
                    default:
147
                        values.add(value);
148
                        break;
149
                    }
150
                }
151
            }
152
            return  values;
153
        } catch (Exception ex) {
154
            String f = "unknow";
155
            try {
156
                f = feature.toString();
157
            } catch (Exception ex2) {
158
                // Do nothing
159
            }
160
            throw new RuntimeException("Can't get parameters to prepared statement from the feature (" + f + ")", ex);
161
        }
162
    }
163

    
164
    public Disposable setParameters(PreparedStatement st, FeatureProvider feature) {
165
        try {
166
            List<Object> values = this.getParameters(feature);
167
            return this.setStatementParameters(st, values, this.geometry_support_type());
168
        } catch (Exception ex) {
169
            String f = "unknow";
170
            try {
171
                f = feature.toString();
172
            } catch (Exception ex2) {
173
                // Do nothing
174
            }
175
            throw new RuntimeException("Can't set parameters to prepared statement from the feature (" + f + ")", ex);
176
        }
177
    }
178
    
179
    protected Geometry forceGeometryType(GeometryType geomtype, Geometry geom) throws CreateGeometryException {
180
        if( geom == null ) {
181
            return null;
182
        }
183
        switch( geomtype.getType() ) {
184
        case Geometry.TYPES.MULTIPOLYGON:
185
            if( geom.getType()==Geometry.TYPES.POLYGON ) {
186
                MultiPolygon x = getGeometryManager().createMultiPolygon(geomtype.getSubType());
187
                x.addPrimitive((Primitive) geom);
188
                geom = x;
189
            }
190
            break;
191
        case Geometry.TYPES.MULTILINE:
192
            if( geom.getType()==Geometry.TYPES.LINE ) {
193
                MultiLine x = getGeometryManager().createMultiLine(geomtype.getSubType());
194
                x.addPrimitive((Primitive) geom);
195
                geom = x;
196
            }
197
            break;
198
        case Geometry.TYPES.MULTIPOINT:
199
            if( geom.getType()==Geometry.TYPES.POINT ) {
200
                MultiLine x = getGeometryManager().createMultiLine(geomtype.getSubType());
201
                x.addPrimitive((Primitive) geom);
202
                geom = x;
203
            }
204
            break;
205
        case Geometry.TYPES.POLYGON:
206
            if( geom.getType()==Geometry.TYPES.MULTIPOLYGON ) {
207
                MultiPolygon x = (MultiPolygon) geom;
208
                if( x.getPrimitivesNumber()==1 ) {
209
                    geom = x.getPrimitiveAt(0);
210
                }
211
            }
212
            break;
213
        case Geometry.TYPES.LINE:
214
            if( geom.getType()==Geometry.TYPES.MULTILINE ) {
215
                MultiLine x = (MultiLine) geom;
216
                if( x.getPrimitivesNumber()==1 ) {
217
                    geom = x.getPrimitiveAt(0);
218
                }
219
            }
220
            break;
221
        case Geometry.TYPES.POINT:
222
            if( geom.getType()==Geometry.TYPES.MULTIPOINT ) {
223
                MultiPoint x = (MultiPoint) geom;
224
                if( x.getPrimitivesNumber()==1 ) {
225
                    geom = x.getPrimitiveAt(0);
226
                }
227
            }
228
        }
229
        return geom;
230
    }
231
    
232
    public Disposable setParameters(PreparedStatement st, FeatureReference reference) {
233
        try {
234
            
235
            List<Object> values = new ArrayList<>();
236
            for (Parameter parameter : this.parameters()) {
237
                if (parameter.is_constant()) {
238
                    values.add(parameter.value());
239
                } else {
240
                    String name = parameter.name();
241
                    values.add(((FeatureReferenceProviderServices)reference).getKeyValue(name));
242
                }
243
            }
244
            return this.setStatementParameters(st, values, this.geometry_support_type());
245
        } catch (Exception ex) {
246
            String f = "unknow";
247
            try {
248
                f = reference.toString();
249
            } catch (Exception ex2) {
250
                // Do nothing
251
            }
252
            throw new RuntimeException("Can't set parameters to prepared statement from the feature (" + f + ")", ex);
253
        }
254
    }
255

    
256
    public Disposable setStatementParameters(
257
        PreparedStatement st, 
258
        List values,
259
        GeometrySupportType geometrySupportType) throws SQLException {
260
        
261
        if (values == null) {
262
            return new Disposable() {
263
                @Override
264
                public void dispose() {
265
                }
266
            };
267
        }
268
        if( LOGGER.isDebugEnabled() ) {
269
            StringBuilder debug = new StringBuilder();
270
            debug.append("[");
271
            debug.append(JDBCUtils.getConnId(st));
272
            debug.append("] st.set(");
273
            try {
274
                byte[] bytes;
275
                int columnIndex = 1;
276
                for (Object value : values) {
277
                    if (value instanceof Geometry) {
278
                        switch(geometrySupportType) {
279
                            case WKT:
280
                                value = ((Geometry) value).convertToWKT();
281
                                debug.append("/*");
282
                                debug.append(columnIndex);
283
                                debug.append("*/ ");
284
                                debug.append(as_string(value));
285
                                debug.append(", ");
286
                                break;
287
                            case NATIVE:
288
                            case WKB: 
289
                                bytes = ((Geometry) value).convertToWKB();
290
                                debug.append("/*");
291
                                debug.append(columnIndex);
292
                                debug.append("*/ ");
293
                                debug.append(as_string(bytes));
294
                                debug.append(", ");
295
                                break;
296
                            case EWKB:
297
                                bytes = ((Geometry) value).convertToEWKB();
298
                                debug.append("/*");
299
                                debug.append(columnIndex);
300
                                debug.append("*/ ");
301
                                debug.append(as_string(bytes));
302
                                debug.append(", ");
303
                                break;
304
                        }
305
                    } else {
306
                        debug.append("/*");
307
                        debug.append(columnIndex);
308
                        debug.append("*/ ");
309
                        if( value instanceof String ) {
310
                            debug.append(as_string(value));
311
                        } else if( value instanceof Boolean ) {
312
                            debug.append( ((Boolean)value)? constant_true:constant_false );
313
                        } else {
314
                            debug.append(value);
315
                        }
316
                        debug.append(", ");
317
                    }
318
                    columnIndex++;
319
                }
320
                debug.append(")");
321
                LOGGER.debug(debug.toString());
322
            } catch(Exception ex) {
323
            }        
324
        }
325
        byte[] bytes;
326
        int columnIndex = 1;
327
        try {
328
            for (Object value : values) {
329
                if (value instanceof Geometry) {
330
                    switch(geometrySupportType) {
331
                        case WKT:
332
                            value = ((Geometry) value).convertToWKT();
333
                            st.setObject(columnIndex, value);
334
                            break;
335
                        case NATIVE:
336
                        case WKB: 
337
                            bytes = ((Geometry) value).convertToWKB();
338
                            st.setBytes(columnIndex, bytes);
339
                            break;
340
                        case EWKB:
341
                            bytes = ((Geometry) value).convertToEWKB();
342
                            st.setBytes(columnIndex, bytes);
343
                            break;
344
                    }
345
                } else {
346
                        st.setObject(columnIndex, value);
347
                    }
348
                columnIndex++;
349
            }
350
            return new Disposable() {
351
                @Override
352
                public void dispose() {
353
                }
354
            };
355
        } catch(Exception ex) {
356
            throw new SQLException("Can't set values for the prepared statement.", ex);
357
        }        
358
    }
359
}