Statistics
| Revision:

gvsig-mssqlserver / trunk / org.gvsig.mssqlserver / org.gvsig.mssqlserver.provider / src / main / java / org / gvsig / mssqlserver / dal / MSSQLServerSQLBuilder.java @ 74

History | View | Annotate | Download (13.9 KB)

1
package org.gvsig.mssqlserver.dal;
2

    
3
import java.text.MessageFormat;
4
import java.util.ArrayList;
5
import java.util.List;
6
import org.cresques.cts.IProjection;
7
import org.gvsig.fmap.dal.DataTypes;
8
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
9
import org.gvsig.fmap.geom.Geometry;
10

    
11
public class MSSQLServerSQLBuilder extends JDBCSQLBuilderBase {
12

    
13
    private final MSSQLServerHelper helper;
14

    
15
    public interface MSSQLServerSQLConfig extends SQLConfig {
16
        public static final String ST_GeomFromTextEx = "ST_GeomFromTextEx";
17
        public static final String ST_GeomFromWKBEx = "ST_GeomFromWKBEx";
18
        public static final String ST_GeomFromEWKBEx = "ST_GeomFromEWKBEx";
19
        public static final String ST_ExtentAggregateEx = "ST_ExtentAggregateEx";
20
        public static final String ST_UnionAggregateEx = "ST_UnionAggregateEx";
21
    }
22
 
23
    public MSSQLServerSQLBuilder(MSSQLServerHelper helper) {
24
        super();
25
        
26
        this.helper = helper;
27
        
28
        config.set(SQLConfig.default_schema, "dbo");
29
        config.set(SQLConfig.allowAutomaticValues, true);
30
        config.set(SQLConfig.geometry_type_support, helper.getGeometrySupportType());
31
        config.set(SQLConfig.has_spatial_functions, helper.hasSpatialFunctions());
32

    
33
        config.remove_functionality(SQLConfig.DELETE_GEOMETRY_COLUMN_FROM_TABLE_schema_table);
34
        config.remove_functionality(SQLConfig.DELETE_GEOMETRY_COLUMN_FROM_TABLE_table);
35
 
36
        config.set(SQLConfig.UPDATE_TABLE_STATISTICS_table,"UPDATE STATISTICS {0}");
37

    
38
        config.set(SQLConfig.type_bytearray, "VARARRAY");
39
        config.set(SQLConfig.type_geometry, "GEOMETRY");
40

    
41
        config.set(SQLConfig.ST_AsText, "({0}).STAsText()");
42
        config.set(SQLConfig.ST_AsBinary, "({0}).STAsBinary()");
43
        config.set(SQLConfig.ST_AsEWKB, "({0}).STAsBinary()");
44
        config.set(SQLConfig.ST_ExtentAggregate, "geometry::EnvelopeAggregate({0})");
45
        config.set(SQLConfig.ST_UnionAggregate, "geometry::UnionAggregate({0})");
46
        config.set(SQLConfig.ST_Contains, "({0}).STContains({1})");
47
        config.set(SQLConfig.ST_Crosses, "({0}).STCrosses({1})");
48
        config.set(SQLConfig.ST_Disjoint, "({0}).STDisjoint({1})");
49
        config.set(SQLConfig.ST_Equals, "({0}).STEquals({1})");
50
        config.set(SQLConfig.ST_IsClosed, "({0}).STIsClosed()");
51
        config.set(SQLConfig.ST_Overlaps, "({0}).STOverlaps({1})");
52
        config.set(SQLConfig.ST_Touches, "({0}).STTouches({1})");
53
        config.set(SQLConfig.ST_Within, "({0}).STWithin ({1})");
54
        config.set(SQLConfig.ST_Envelope, "({0}).STEnvelope()");
55
        config.set(SQLConfig.ST_Intersects, "({0}).STIntersects({1})");
56
        config.set(SQLConfig.ST_GeomFromText, "geometry::STGeomFromText({0}, {1})");
57
        config.set(SQLConfig.ST_GeomFromWKB, "geometry::STGeomFromWKB({0}, {1})");
58
        config.set(SQLConfig.ST_GeomFromEWKB, "geometry::STGeomFromWKB({0}, {1})");
59
        config.set(SQLConfig.ST_Simplify, "({0}).Reduce({1})");
60
        config.set(SQLConfig.lcase, "LOWER({0})");
61
        config.set(SQLConfig.ucase, "UPPER({0})");
62
        config.set(SQLConfig.operator_ILIKE, "LOWER({0}) LIKE LOWER({1})");
63

    
64
        config.set(MSSQLServerSQLConfig.ST_ExtentAggregateEx, "{1}::EnvelopeAggregate({0})");
65
        config.set(MSSQLServerSQLConfig.ST_UnionAggregateEx, "{1}::UnionAggregate({0})");
66
        config.set(MSSQLServerSQLConfig.ST_GeomFromTextEx, "{2}::STGeomFromText({0}, {1})");
67
        config.set(MSSQLServerSQLConfig.ST_GeomFromWKBEx, "{2}::STGeomFromWKB({0}, {1})");
68
        config.set(MSSQLServerSQLConfig.ST_GeomFromEWKBEx, "{2}::STGeomFromWKB({0}, {1})");
69

    
70
    }
71

    
72
    @Override
73
    public MSSQLServerSQLConfig getConfig() {
74
        return (MSSQLServerSQLConfig) super.config;
75
    }
76

    
77
    public class MSSQLServerParameter extends ParameterBase {
78

    
79
        public MSSQLServerParameter() {
80
            super();
81
        }
82

    
83
        @Override
84
        public String toString() {
85
            if( this.type == ParameterType.Geometry ) {
86
                String spatialType = helper.getSpatialType(this.getName());
87
                switch( config.getGeometryTypeSupport() ) {
88
                    case EWKB:
89
                        return MessageFormat.format(
90
                                config.getString(MSSQLServerSQLConfig.ST_GeomFromEWKBEx),
91
                                "?",
92
                                String.valueOf(this.srs.toString()),
93
                                custom(spatialType)
94
                        );
95
                    case WKB:
96
                        return MessageFormat.format(
97
                                config.getString(MSSQLServerSQLConfig.ST_GeomFromWKBEx),
98
                                "?",
99
                                String.valueOf(this.srs.toString()),
100
                                custom(spatialType)
101
                        );
102
                    case WKT:
103
                    default:
104
                        return MessageFormat.format(
105
                                config.getString(MSSQLServerSQLConfig.ST_GeomFromTextEx),
106
                                "?",
107
                                String.valueOf(this.srs.toString()),
108
                                custom(spatialType)
109
                        );                        
110
                }                            
111
            }
112
            return super.toString();
113
        }
114
    }
115
    
116
    public class MSSQLServerGeometryValue extends GeometryValueBase {
117
        
118
        public MSSQLServerGeometryValue(Geometry geometry, IProjection projection) {
119
            super(geometry, projection);
120
        }
121
        
122
        @Override
123
        public String toString() {
124
            try {
125
                String spatialType = helper.getSpatialType();
126
                switch( config.getGeometryTypeSupport() ) {
127
                    case EWKB:
128
                        return MessageFormat.format(
129
                                config.getString(MSSQLServerSQLConfig.ST_GeomFromEWKBEx),
130
                                bytearray(this.geometry.convertToEWKB()),
131
                                String.valueOf(getSRSId(this.projection)),
132
                                custom(spatialType)
133
                        );
134
                    case WKB:
135
                        return MessageFormat.format(
136
                                config.getString(MSSQLServerSQLConfig.ST_GeomFromWKBEx),
137
                                bytearray(this.geometry.convertToWKB()),
138
                                String.valueOf(getSRSId(this.projection)),
139
                                custom(spatialType)
140
                        );
141
                    case WKT:
142
                    default:
143
                        return MessageFormat.format(
144
                                config.getString(MSSQLServerSQLConfig.ST_GeomFromTextEx),
145
                                string(this.geometry.convertToWKT()),
146
                                String.valueOf(getSRSId(this.projection)),
147
                                custom(spatialType)
148
                        );                        
149
                }
150
            } catch (Exception ex) {
151
                throw new RuntimeException("Can't convert geometry to string.",ex);
152
            }
153
        }
154
    }
155

    
156
    protected class MSSQLServerSelectBuilder extends SelectBuilderBase {
157

    
158
        @Override
159
        public String toString() {
160
            // MSSQLServer usa TOP en lugar de LIMIT y la sintaxis para OFFSET
161
            // es ligeramente distinta de la que hay en SelectBuilderBase
162
            StringBuilder builder = new StringBuilder();
163

    
164
            builder.append("SELECT ");
165
            if( this.distinct ) {
166
                builder.append("DISTINCT ");
167
            }
168
            if (this.has_limit()) {
169
                builder.append("TOP ");
170
                builder.append(this.limit);
171
                builder.append(" ");
172
           }
173
            boolean first = true;
174
            for (SelectColumnBuilder column : columns) {
175
                if (first) {
176
                    first = false;
177
                } else {
178
                    builder.append(", ");
179
                }
180
                builder.append(column.toString());
181
            }
182

    
183
            if (this.has_from()) {
184
                builder.append(" FROM ");
185
                builder.append(this.from.toString());
186
            }
187
            if (this.has_where()) {
188
                builder.append(" WHERE ");
189
                builder.append(this.where.toString());
190
            }
191

    
192
            if( this.has_order_by() ) {
193
                builder.append(" ORDER BY ");
194
                first = true;
195
                for (OrderByBuilder item : this.order_by) {
196
                    if (first) {
197
                        first = false;
198
                    } else {
199
                        builder.append(", ");
200
                    }
201
                    builder.append(item.toString());
202
                }
203
            }
204

    
205
            if (this.has_offset()) {
206
                // Require SQLSeerver >= 2012
207
                builder.append(" OFFSET ");
208
                builder.append(this.offset);
209
                builder.append(" ROWS");
210

    
211
            }
212
            return builder.toString();
213
        }
214
    }
215

    
216
    protected class MSSQLServerCreateTableBuilder extends CreateTableBuilderBase {
217

    
218
        @Override
219
        public List<String> toStrings() {
220
            //
221
            // Respecto al base cambia la declaracion de campo automaticos
222
            // SQLServer usa IDENTITY en lugar de SERIAL.
223
            //
224
            List<String> sqls = new ArrayList<>();
225
            StringBuilder builder = new StringBuilder();
226

    
227
            builder.append("CREATE TABLE ");
228
            builder.append(this.table.toString());
229
            builder.append(" (");
230
            boolean first = true;
231
            for (ColumnDescriptorBuilder column : columns) {
232
                if (first) {
233
                    first = false;
234
                } else {
235
                    builder.append(", ");
236
                }
237
                builder.append(identifier(column.getName()));
238
                builder.append(" ");
239
                if( column.isAutomatic() && column.getType() == DataTypes.INT ) {
240
                    builder.append("INT");
241
                    builder.append(" IDENTITY(1,1)");
242
                } else if( column.isAutomatic() && column.getType() == DataTypes.LONG ) {
243
                    builder.append("BIGINT");
244
                    builder.append(" IDENTITY(1,1)");
245
                } else {
246
                    builder.append(sqltype(column.getType(), column.getPrecision(), column.getSize()));
247
                }
248
                if (column.getDefaultValue() == null) {
249
                    if (column.allowNulls()) {
250
                        builder.append(" DEFAULT NULL");
251
                    }
252
                } else {
253
                    builder.append(" DEFAULT '");
254
                    builder.append(column.getDefaultValue().toString());
255
                    builder.append("'");
256
                }
257
                if (column.allowNulls()) {
258
                    builder.append(" NULL");
259
                } else {
260
                    builder.append(" NOT NULL");
261
                }
262
                if (column.isPrimaryKey()) {
263
                    builder.append(" PRIMARY KEY");
264
                }
265
            }
266
            builder.append(" )");
267
            sqls.add(builder.toString());
268

    
269
            return sqls;
270
        }
271
    }
272

    
273
    @Override
274
    protected SelectBuilder createSelectBuilder() {
275
        return new MSSQLServerSelectBuilder();
276
    }
277

    
278
    @Override
279
    protected CreateTableBuilder createCreateTableBuilder() {
280
        return new MSSQLServerCreateTableBuilder();
281
    }
282

    
283
    @Override
284
    public String identifier(String id) {
285
        // En SQLServer se aceptan las comillas dobles pero se prefiere
286
        // corchetes [xx]. Asi que si hay comillas dobles las quitamos
287
        // y ponemos los corchetes.
288
        String quote = config.getString(Config.quote_for_identifiers);
289
        if (id.startsWith(quote)) {
290
            id = id.substring(1, id.length()-1);
291
        } else if( id.startsWith("[") ) {
292
            return id;
293
        }
294
        if( id.contains("(") ) {
295
            logger.warn("Suspicious use of 'identifier' in sql.");
296
        }
297
        return "[" + id + "]";
298
    }
299

    
300
    @Override
301
    public GeometryValue geometry(Geometry geom, IProjection projection) {
302
        return new MSSQLServerGeometryValue(geom, projection);
303
    }
304

    
305
    @Override
306
    public Parameter parameter() {
307
        return new MSSQLServerParameter();
308
    }
309
    
310
    @Override
311
    public Function ST_ExtentAggregate(Value geom) {
312
        String spatialType = helper.getSpatialType();
313
        return function("ST_ExtentAggregate", 
314
                config.getString(MSSQLServerSQLConfig.ST_ExtentAggregateEx), 
315
                geom,
316
                custom(spatialType)
317
        );
318
    }
319

    
320
    @Override
321
    public Function ST_UnionAggregate(Value geom) {
322
        String spatialType = helper.getSpatialType();
323
        return function("ST_UnionAggregate", 
324
                config.getString(MSSQLServerSQLConfig.ST_UnionAggregateEx), 
325
                geom,
326
                custom(spatialType)
327
        );
328
    }
329

    
330
    @Override
331
    public Function ST_GeomFromText(Value geom, Value crs) {
332
        String spatialType = helper.getSpatialType();
333
        return function("ST_GeomFromText", 
334
                config.getString(MSSQLServerSQLConfig.ST_GeomFromTextEx), 
335
                geom, 
336
                crs,
337
                custom(spatialType)
338
        );
339
    }
340

    
341
    @Override
342
    public Function ST_GeomFromWKB(Value geom, Value crs) {
343
        String spatialType = helper.getSpatialType();
344
        return function("ST_GeomFromWKB", 
345
                config.getString(MSSQLServerSQLConfig.ST_GeomFromWKBEx), 
346
                geom, 
347
                crs,
348
                custom(spatialType)
349
        );
350
    }
351

    
352
    @Override
353
    public Function ST_GeomFromEWKB(Value geom, Value crs) {
354
        String spatialType = helper.getSpatialType();
355
        return function("ST_GeomFromEWKB", 
356
                config.getString(MSSQLServerSQLConfig.ST_GeomFromEWKBEx), 
357
                geom, 
358
                crs,
359
                custom(spatialType)
360
        );
361
    }
362

    
363
}