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 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 43687 jjdelcerro
import java.sql.Connection;
27 43020 jjdelcerro
import java.sql.PreparedStatement;
28 43629 jjdelcerro
import java.sql.SQLException;
29 43020 jjdelcerro
import java.util.ArrayList;
30 44323 jjdelcerro
import java.util.Date;
31 43020 jjdelcerro
import java.util.List;
32 43687 jjdelcerro
import org.cresques.cts.IProjection;
33 44198 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionBuilder.Parameter;
34 44644 jjdelcerro
import static org.gvsig.expressionevaluator.GeometryExpressionBuilderHelper.GeometrySupportType;
35 43687 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
36 43479 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureReference;
37 43687 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureType;
38 43093 jjdelcerro
import org.gvsig.fmap.dal.feature.spi.SQLBuilderBase;
39 43020 jjdelcerro
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
40 43479 jjdelcerro
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
41 43687 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
42 45097 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
43 43629 jjdelcerro
import org.gvsig.fmap.geom.Geometry;
44 43687 jjdelcerro
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 43629 jjdelcerro
import org.gvsig.tools.dispose.Disposable;
53 43020 jjdelcerro
54 44198 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
55 43020 jjdelcerro
public class JDBCSQLBuilderBase extends SQLBuilderBase {
56
57 44198 jjdelcerro
    public static final String PROP_FEATURE_TYPE = "FeatureType";
58
    public static final String PROP_TABLE = "Table";
59
60 43687 jjdelcerro
    private GeometryManager geometryManager = null;
61
    protected final JDBCHelper helper;
62
63
    public JDBCSQLBuilderBase(JDBCHelper helper) {
64 43020 jjdelcerro
        super();
65 43687 jjdelcerro
        this.helper = helper;
66 43020 jjdelcerro
    }
67 43687 jjdelcerro
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 44198 jjdelcerro
    public Object srs_id(IProjection projection) {
81 43687 jjdelcerro
        Connection conn = null;
82
        try {
83
            conn = this.helper.getConnection();
84
            SRSSolver solver = this.helper.getSRSSolver();
85
            Object srscode = solver.getDatabaseCode(conn, projection);
86 43737 jjdelcerro
//            logger.debug("database code srs {}, type {}, srssolver {}.",
87
//                new Object[] {
88
//                    srscode,
89
//                    srscode==null? "null":srscode.getClass().getSimpleName(),
90
//                    solver
91
//                }
92
//            );
93 43687 jjdelcerro
            return srscode;
94
        } catch (Exception ex) {
95
            throw new RuntimeException("Can't locate database code for SRS '"+projection.getAbrev()+"'.");
96
        } finally {
97 44191 jjdelcerro
            this.helper.closeConnectionQuietly(conn);
98 43687 jjdelcerro
        }
99
    }
100
101 43093 jjdelcerro
    public void setParameters(PreparedStatement st) {
102
        try {
103
            int columnIndex = 1;
104 44198 jjdelcerro
            for (Parameter parameter : this.parameters()) {
105
                st.setObject(columnIndex++, parameter.value());
106 43093 jjdelcerro
            }
107
        } catch (Exception ex) {
108
            String p = "unknow";
109
            try {
110 44198 jjdelcerro
                p =  this.parameters().toString();
111 43093 jjdelcerro
            } 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 44678 jjdelcerro
    public List<Object> getParameters(FeatureProvider feature) {
119 43020 jjdelcerro
        try {
120 43687 jjdelcerro
            FeatureType type = feature.getType();
121 43020 jjdelcerro
            List<Object> values = new ArrayList<>();
122 43687 jjdelcerro
            Object value;
123 44198 jjdelcerro
            for (Parameter parameter : this.parameters()) {
124 43093 jjdelcerro
                if (parameter.is_constant()) {
125 44198 jjdelcerro
                    value = parameter.value();
126 43687 jjdelcerro
                    values.add(value);
127 43020 jjdelcerro
                } else {
128 44198 jjdelcerro
                    String name = parameter.name();
129 43687 jjdelcerro
                    value = feature.get(name);
130
                    FeatureAttributeDescriptor attrDesc = type.getAttributeDescriptor(name);
131 44323 jjdelcerro
                    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 43687 jjdelcerro
                    }
150 43020 jjdelcerro
                }
151
            }
152 44678 jjdelcerro
            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 43629 jjdelcerro
            return this.setStatementParameters(st, values, this.geometry_support_type());
168 43020 jjdelcerro
        } catch (Exception ex) {
169 43093 jjdelcerro
            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 43020 jjdelcerro
        }
177
    }
178 43687 jjdelcerro
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 43629 jjdelcerro
    public Disposable setParameters(PreparedStatement st, FeatureReference reference) {
233 43479 jjdelcerro
        try {
234
235
            List<Object> values = new ArrayList<>();
236 44198 jjdelcerro
            for (Parameter parameter : this.parameters()) {
237 43479 jjdelcerro
                if (parameter.is_constant()) {
238 44198 jjdelcerro
                    values.add(parameter.value());
239 43479 jjdelcerro
                } else {
240 44198 jjdelcerro
                    String name = parameter.name();
241 43479 jjdelcerro
                    values.add(((FeatureReferenceProviderServices)reference).getKeyValue(name));
242
                }
243
            }
244 43629 jjdelcerro
            return this.setStatementParameters(st, values, this.geometry_support_type());
245 43479 jjdelcerro
        } 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 43629 jjdelcerro
    public Disposable setStatementParameters(
257
        PreparedStatement st,
258 44944 omartinez
        List values,
259 43629 jjdelcerro
        GeometrySupportType geometrySupportType) throws SQLException {
260
261
        if (values == null) {
262
            return new Disposable() {
263
                @Override
264
                public void dispose() {
265
                }
266
            };
267
        }
268 44198 jjdelcerro
        if( LOGGER.isDebugEnabled() ) {
269 43732 jjdelcerro
            StringBuilder debug = new StringBuilder();
270 45097 jjdelcerro
            debug.append("[");
271
            debug.append(JDBCUtils.getConnId(st));
272
            debug.append("] st.set(");
273 43732 jjdelcerro
            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 44198 jjdelcerro
                                debug.append(as_string(value));
285 43732 jjdelcerro
                                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 44198 jjdelcerro
                                debug.append(as_string(bytes));
294 43732 jjdelcerro
                                debug.append(", ");
295
                                break;
296
                            case EWKB:
297
                                bytes = ((Geometry) value).convertToEWKB();
298
                                debug.append("/*");
299
                                debug.append(columnIndex);
300
                                debug.append("*/ ");
301 44198 jjdelcerro
                                debug.append(as_string(bytes));
302 43732 jjdelcerro
                                debug.append(", ");
303
                                break;
304
                        }
305
                    } else {
306
                        debug.append("/*");
307
                        debug.append(columnIndex);
308
                        debug.append("*/ ");
309
                        if( value instanceof String ) {
310 44198 jjdelcerro
                            debug.append(as_string(value));
311 43732 jjdelcerro
                        } else if( value instanceof Boolean ) {
312 44198 jjdelcerro
                            debug.append( ((Boolean)value)? constant_true:constant_false );
313 43732 jjdelcerro
                        } else {
314
                            debug.append(value);
315
                        }
316
                        debug.append(", ");
317
                    }
318
                    columnIndex++;
319
                }
320
                debug.append(")");
321 44198 jjdelcerro
                LOGGER.debug(debug.toString());
322 43732 jjdelcerro
            } catch(Exception ex) {
323
            }
324
        }
325 44944 omartinez
        byte[] bytes;
326
        int columnIndex = 1;
327 43629 jjdelcerro
        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 44944 omartinez
                        st.setObject(columnIndex, value);
347
                    }
348 43629 jjdelcerro
                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 43020 jjdelcerro
}