Statistics
| Revision:

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

History | View | Annotate | Download (13.8 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 MSSQLServerSQLHelper 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(MSSQLServerSQLHelper 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.lcase, "LOWER({0})");
60
        config.set(SQLConfig.ucase, "UPPER({0})");
61
        config.set(SQLConfig.operator_ILIKE, "LOWER({0}) LIKE LOWER({1})");
62

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

    
69
    }
70

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

    
76
    public class MSSQLServerParameter extends ParameterBase {
77

    
78
        public MSSQLServerParameter(Object value) {
79
            super(value);
80
        }
81

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

    
155
    protected class MSSQLServerSelectBuilder extends SelectBuilderBase {
156

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

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

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

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

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

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

    
215
    protected class MSSQLServerCreateTableBuilder extends CreateTableBuilderBase {
216

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

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

    
268
            return sqls;
269
        }
270
    }
271

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

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

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

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

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

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

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

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

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

    
362
}