Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_daldb / src / org / gvsig / fmap / dal / store / mysql / MySQLHelper.java @ 28967

History | View | Annotate | Download (11.4 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
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 2
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
*/
22

    
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2009 IVER T.I   {{Task}}
26
*/
27

    
28
/**
29
 *
30
 */
31
package org.gvsig.fmap.dal.store.mysql;
32

    
33
import java.sql.Connection;
34
import java.sql.ResultSet;
35
import java.sql.ResultSetMetaData;
36
import java.sql.SQLException;
37
import java.sql.Statement;
38

    
39
import org.gvsig.fmap.dal.DALLocator;
40
import org.gvsig.fmap.dal.DataTypes;
41
import org.gvsig.fmap.dal.exception.DataException;
42
import org.gvsig.fmap.dal.exception.InitializeException;
43
import org.gvsig.fmap.dal.exception.ReadException;
44
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
45
import org.gvsig.fmap.dal.feature.EditableFeatureType;
46
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
47
import org.gvsig.fmap.dal.feature.exception.UnsupportedDataTypeException;
48
import org.gvsig.fmap.dal.resource.spi.ResourceManagerProviderServices;
49
import org.gvsig.fmap.dal.store.jdbc.JDBCHelper;
50
import org.gvsig.fmap.dal.store.jdbc.JDBCHelperUser;
51
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
52
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCException;
53
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecuteSQLException;
54
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
55
import org.gvsig.fmap.geom.Geometry;
56
import org.gvsig.fmap.geom.GeometryLocator;
57
import org.gvsig.fmap.geom.GeometryManager;
58
import org.gvsig.fmap.geom.operation.fromwkb.FromWKB;
59
import org.gvsig.fmap.geom.operation.fromwkb.FromWKBGeometryOperationContext;
60
import org.gvsig.fmap.geom.primitive.Envelope;
61
import org.gvsig.tools.exception.BaseException;
62
import org.slf4j.Logger;
63
import org.slf4j.LoggerFactory;
64

    
65
/**
66
 * @author jmvivo
67
 *
68
 */
69
public class MySQLHelper extends JDBCHelper {
70

    
71
        private static Logger logger = LoggerFactory
72
                        .getLogger(MySQLHelper.class);
73

    
74

    
75
        MySQLHelper(JDBCHelperUser consumer,
76
                        MySQLConnectionParameters params)
77
                        throws InitializeException {
78

    
79
                super(consumer, params);
80
        }
81

    
82
        protected void initializeResource() throws InitializeException {
83
                ResourceManagerProviderServices manager = (ResourceManagerProviderServices) DALLocator
84
                .getResourceManager();
85
                MySQLResource resource = (MySQLResource) manager
86
                .createResource(
87
                                MySQLResource.NAME, new Object[] {
88
                                                params.getUrl(), params.getHost(),
89
                                                params.getPort(), params.getDBName(), params.getUser(),
90
                                                params.getPassword(),
91
                                                params.getJDBCDriverClassName(),
92
                                                ((MySQLConnectionParameters) params).getUseSSL() });
93
                this.setResource(resource);
94
        }
95

    
96

    
97
        protected String getDefaultSchema(Connection conn)
98
                        throws JDBCException {
99
                if (defaultSchema == null) {
100
                        defaultSchema = params.getDBName();
101
                }
102

    
103
                return defaultSchema;
104
        }
105

    
106
        public Envelope getFullEnvelopeOfField(
107
                        JDBCStoreParameters storeParams,
108
                        String geometryAttrName, Envelope limit)
109
                        throws DataException {
110

    
111
                StringBuilder strb = new StringBuilder();
112
                strb.append("Select asbinary(envelope(");
113
                strb.append(geometryAttrName);
114
                strb.append(")) from ");
115

    
116
                if (storeParams.getSQL() != null
117
                                && storeParams.getSQL().trim().length() == 0) {
118
                        strb.append('(');
119
                        strb.append(storeParams.getSQL());
120
                        strb.append(") as __tmp__ ");
121
                } else {
122
                        strb.append(storeParams.tableID());
123
                }
124

    
125

    
126
                if (limit != null){
127
                        strb.append(" where  intersects(GeomFromText('");
128
                        strb.append(limit.toString());
129
                        strb.append("')), boundary(");
130
                        strb.append(geometryAttrName);
131
                        strb.append(")) ");
132
                }
133

    
134
                String sql = strb.toString();
135

    
136

    
137
                ResultSet rs = null;
138
                Statement st = null;
139
                String schema = null;
140
                Connection conn = null;
141

    
142
                GeometryManager geoMan = GeometryLocator.getGeometryManager();
143

    
144
                Envelope fullEnvelope = null;
145
                try {
146
                        initializeFromWKBOperation();
147
                } catch (BaseException e1) {
148
                        throw new ReadException(this.name, e1);
149
                }
150

    
151
                this.open();
152
                this.begin();
153
                try{
154
                        conn = getConnection();
155
                        st = conn.createStatement();
156
                        try {
157
                                rs = st.executeQuery(sql);
158
                        } catch (java.sql.SQLException e) {
159
                                throw new JDBCExecuteSQLException(sql, e);
160
                        }
161
                        while (rs.next()) {
162

    
163
                                byte[] data = rs.getBytes(1);
164
                                if (data == null) {
165
                                        continue;
166
                                }
167

    
168
                                fromWKBContext.setData(data);
169
                                Geometry geom = (Geometry) fromWKB.invoke(null, fromWKBContext);
170

    
171
                                if (fullEnvelope == null) {
172
                                        fullEnvelope = geom.getEnvelope();
173
                                } else {
174
                                        fullEnvelope.add(geom.getEnvelope());
175
                                }
176
                        }
177

    
178
                        return fullEnvelope;
179
                } catch (java.sql.SQLException e) {
180
                        throw new JDBCSQLException(e);
181
                } catch (BaseException e) {
182
                        throw new ReadException(user.getName(), e);
183
                } finally {
184
                        try{ rs.close(); } catch (Exception e){};
185
                        try{ st.close(); } catch (Exception e){};
186
                        try{ conn.close(); } catch (Exception e){};
187
                        rs = null;
188
                        st = null;
189
                        conn = null;
190
                        end();
191
                }
192

    
193

    
194
        }
195

    
196
        protected void initializeFromWKBOperation() throws BaseException {
197
                if (fromWKB == null) {
198
                        fromWKB = (FromWKB) GeometryLocator.getGeometryManager()
199
                                        .getGeometryOperation(FromWKB.CODE,
200
                                                        Geometry.TYPES.GEOMETRY, Geometry.SUBTYPES.GEOM2D);
201
                        fromWKBContext = new FromWKBGeometryOperationContext();
202

    
203
                }
204
        }
205

    
206
        public Geometry getGeometry(byte[] buffer) throws BaseException {
207
                if (buffer == null) {
208
                        return null;
209
                }
210
                initializeFromWKBOperation();
211
                Geometry geom;
212
                try {
213
                        fromWKBContext.setData(buffer);
214

    
215
                        geom = (Geometry) fromWKB.invoke(null, fromWKBContext);
216
                } finally {
217
                        fromWKBContext.setData(null);
218
                }
219
                return geom;
220
        }
221

    
222
        public String getSqlColumnTypeDescription(FeatureAttributeDescriptor attr) {
223

    
224
                switch (attr.getDataType()) {
225
                case DataTypes.STRING:
226
                        return "VARCHAR(" + attr.getSize() + ")";
227
                case DataTypes.BOOLEAN:
228
                        return "BOOL";
229

    
230
                case DataTypes.BYTE:
231
                        return "TINYINT UNSIGNED";
232

    
233
                case DataTypes.DATE:
234
                        return "DATE";
235

    
236
                case DataTypes.TIMESTAMP:
237
                        return "TIMESTAMP";
238

    
239
                case DataTypes.TIME:
240
                        return "TIME";
241

    
242
                case DataTypes.BYTEARRAY:
243
                        if (attr.getSize() > 0) {
244
                                return "BLOB(" + attr.getSize() + ")";
245
                        } else {
246
                                return "BLOB";
247
                        }
248

    
249
                case DataTypes.DOUBLE:
250
                        if (attr.getSize() > 0) {
251
                                return "DOUBLE(" + attr.getSize() + "," + attr.getPrecision()
252
                                                + ")";
253
                        } else {
254
                                return "DOBLE";
255
                        }
256
                case DataTypes.FLOAT:
257
                        return "FLOAT";
258

    
259
                case DataTypes.GEOMETRY:
260
                        switch (attr.getGeometryType()) {
261
                        case Geometry.TYPES.POINT:
262
                                return "POINT";
263
                        case Geometry.TYPES.CURVE:
264
                                return "LINESTRING";
265
                        case Geometry.TYPES.SURFACE:
266
                                return "SURFACE";
267
                        case Geometry.TYPES.SOLID:
268
                                return "POLYGON";
269

    
270
                        case Geometry.TYPES.MULTIPOINT:
271
                                return "MULTIPOIN";
272
                        case Geometry.TYPES.MULTICURVE:
273
                                return "MULTILINESTRING";
274
                        case Geometry.TYPES.MULTISURFACE:
275
                                return "MULTISURFACE";
276
                        case Geometry.TYPES.MULTISOLID:
277
                                return "MULTIPOLYGON";
278

    
279
                        default:
280
                                return "GEOMETRY";
281
                        }
282
                case DataTypes.INT:
283
                        if (attr.getSize() > 0) {
284
                                return "INT(" + attr.getSize() + ")";
285
                        }
286
                case DataTypes.LONG:
287
                        return "BIGINT";
288

    
289
                default:
290
                        String typeName = (String) attr.getAdditionalInfo("SQLTypeName");
291
                        if (typeName != null) {
292
                                return typeName;
293
                        }
294

    
295
                        throw new UnsupportedDataTypeException(attr.getDataTypeName(), attr
296
                                        .getDataType());
297
                }
298
        }
299

    
300

    
301
        public String getSqlFieldName(FeatureAttributeDescriptor attribute) {
302
                if (attribute.getDataType() == DataTypes.GEOMETRY) {
303
                        return "asBinary(" + super.getSqlFieldName(attribute) + ")";
304
                }
305
                return super.getSqlFieldName(attribute);
306
        }
307

    
308
        protected EditableFeatureAttributeDescriptor createAttributeFromJDBC(
309
                        EditableFeatureType type, Connection conn,
310
                        ResultSetMetaData rsMetadata, int colIndex) throws SQLException {
311
                int colType = rsMetadata.getColumnType(colIndex);
312
                if (colType == java.sql.Types.OTHER || colType == java.sql.Types.STRUCT
313
                                || colType == java.sql.Types.BLOB
314
                                || colType == java.sql.Types.BINARY) {
315
                        Integer geoType = null;
316

    
317
                        if (rsMetadata.getColumnTypeName(colIndex).equalsIgnoreCase(
318
                                        "geometry")) {
319
                                geoType = new Integer(Geometry.TYPES.GEOMETRY);
320
                        } else if (rsMetadata.getColumnTypeName(colIndex).equalsIgnoreCase("POINT")) {
321
                                geoType = new Integer(Geometry.TYPES.POINT);
322
                        } else if (rsMetadata.getColumnTypeName(colIndex).equalsIgnoreCase("LINESTRING")) {
323
                                geoType = new Integer(Geometry.TYPES.CURVE);
324
                        } else if (rsMetadata.getColumnTypeName(colIndex).equalsIgnoreCase("SURFACE")) {
325
                                geoType = new Integer(Geometry.TYPES.SURFACE);
326
                        } else if (rsMetadata.getColumnTypeName(colIndex).equalsIgnoreCase("POLYGON")) {
327
                                geoType = new Integer(Geometry.TYPES.SOLID);
328
                        } else if (rsMetadata.getColumnTypeName(colIndex).equalsIgnoreCase("MULTIPOIN")) {
329
                                geoType = new Integer(Geometry.TYPES.MULTIPOINT);
330
                        } else if (rsMetadata.getColumnTypeName(colIndex).equalsIgnoreCase("MULTILINESTRING")) {
331
                                geoType = new Integer(Geometry.TYPES.MULTICURVE);
332
                        } else if (rsMetadata.getColumnTypeName(colIndex).equalsIgnoreCase(
333
                                        "MULTISURFACE")) {
334
                                geoType = new Integer(Geometry.TYPES.MULTISURFACE);
335
                        } else if (rsMetadata.getColumnTypeName(colIndex).equalsIgnoreCase(
336
                                        "MULTIPOLYGON")) {
337
                                geoType = new Integer(Geometry.TYPES.MULTISOLID);
338
                        }
339
                        if (geoType != null){
340
                                EditableFeatureAttributeDescriptor attr = type.add(rsMetadata
341
                                                .getColumnName(colIndex), DataTypes.GEOMETRY);
342
                                attr.setGeometryType(geoType.intValue());
343
                                attr.setGeometrySubType(Geometry.SUBTYPES.GEOM2D);
344

    
345
                                return attr;
346
                        }
347

    
348
                }
349

    
350
                return super.createAttributeFromJDBC(type, conn, rsMetadata, colIndex);
351
        }
352

    
353
        public String escapeFieldName(String field) {
354
                if (field.matches("[a-z][a-z0-9_]*")) {
355
                        return field;
356
                }
357
                return "`" + field + "`";
358
        }
359

    
360

    
361
        public boolean allowAutomaticValues() {
362
                return Boolean.TRUE;
363
        }
364

    
365

    
366
        public String getSqlFieldDescription(FeatureAttributeDescriptor attr)
367
                        throws DataException {
368

    
369
                /**
370
                        column_definition:
371
                            data_type [NOT NULL | NULL] [DEFAULT default_value]
372
                              [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY]
373
                              [COMMENT 'string'] [reference_definition]
374

375
                 */
376

    
377
                StringBuilder strb = new StringBuilder();
378
                // name
379
                strb.append(escapeFieldName(attr.getName()));
380
                strb.append(" ");
381

    
382
                // Type
383
                strb.append(this.getSqlColumnTypeDescription(attr));
384
                strb.append(" ");
385

    
386
                boolean allowNull = attr.allowNull()
387
                                && !(attr.isPrimaryKey() || attr.isAutomatic());
388

    
389
                // Null
390
                if (allowNull) {
391
                        strb.append("NULL ");
392
                } else {
393
                        strb.append("NOT NULL ");
394
                }
395
                if (attr.isAutomatic()) {
396
                        strb.append("AUTO_INCREMENT ");
397
                }
398

    
399
                // Default
400
                if (attr.getDefaultValue() == null) {
401
                        if (allowNull) {
402
                                strb.append("DEFAULT NULL ");
403
                        }
404
                } else {
405
                        String value = getDefaltFieldValueString(attr);
406
                        strb.append("DEFAULT '");
407
                        strb.append(value);
408
                        strb.append("' ");
409
                }
410

    
411
                // Primery key
412
                if (attr.isPrimaryKey()) {
413
                        strb.append("PRIMARY KEY ");
414
                }
415
                return strb.toString();
416
        }
417

    
418
        public boolean supportOffset() {
419
                return true;
420
        }
421

    
422
        public boolean supportsUnion() {
423
                return true;
424
        }
425

    
426

    
427
}