Statistics
| Revision:

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

History | View | Annotate | Download (14.2 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
    public interface MSSQLServerSQLConfig extends SQLConfig {
14
        public static final String ST_GeomFromTextEx = "ST_GeomFromTextEx";
15
        public static final String ST_GeomFromWKBEx = "ST_GeomFromWKBEx";
16
        public static final String ST_GeomFromEWKBEx = "ST_GeomFromEWKBEx";
17
        public static final String ST_ExtentAggregateEx = "ST_ExtentAggregateEx";
18
        public static final String ST_UnionAggregateEx = "ST_UnionAggregateEx";
19
    }
20
 
21
    public MSSQLServerSQLBuilder(MSSQLServerHelper helper) {
22
        super(helper);
23
        
24
        config.set(SQLConfig.default_schema, "dbo");
25
        config.set(SQLConfig.allowAutomaticValues, true);
26
        config.set(SQLConfig.geometry_type_support, helper.getGeometrySupportType());
27
        config.set(SQLConfig.has_spatial_functions, helper.hasSpatialFunctions());
28

    
29
        config.remove_functionality(SQLConfig.DELETE_GEOMETRY_COLUMN_FROM_TABLE_schema_table);
30
        config.remove_functionality(SQLConfig.DELETE_GEOMETRY_COLUMN_FROM_TABLE_table);
31
 
32
        config.set(SQLConfig.UPDATE_TABLE_STATISTICS_table,"UPDATE STATISTICS {0}");
33

    
34
        config.set(SQLConfig.type_bytearray, "VARARRAY");
35
        config.set(SQLConfig.type_geometry, "GEOMETRY");
36

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

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

    
66
    }
67

    
68
    @Override
69
    public MSSQLServerSQLConfig getConfig() {
70
        return (MSSQLServerSQLConfig) super.config;
71
    }
72

    
73
    public MSSQLServerHelper getHelper() {
74
        return (MSSQLServerHelper) helper;
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 = getHelper().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 NATIVE:
96
                    case WKB:
97
                        return MessageFormat.format(
98
                                config.getString(MSSQLServerSQLConfig.ST_GeomFromWKBEx),
99
                                "?",
100
                                String.valueOf(this.srs.toString()),
101
                                custom(spatialType)
102
                        );
103
                    case WKT:
104
                    default:
105
                        return MessageFormat.format(
106
                                config.getString(MSSQLServerSQLConfig.ST_GeomFromTextEx),
107
                                "?",
108
                                String.valueOf(this.srs.toString()),
109
                                custom(spatialType)
110
                        );                        
111
                }                            
112
            }
113
            return super.toString();
114
        }
115
    }
116
    
117
    public class MSSQLServerGeometryValue extends GeometryValueBase {
118
        
119
        public MSSQLServerGeometryValue(Geometry geometry, IProjection projection) {
120
            super(geometry, projection);
121
        }
122
        
123
        @Override
124
        public String toString() {
125
            try {
126
                String spatialType = getHelper().getSpatialType();
127
                switch( config.getGeometryTypeSupport() ) {
128
                    case EWKB:
129
                        return MessageFormat.format(
130
                                config.getString(MSSQLServerSQLConfig.ST_GeomFromEWKBEx),
131
                                bytearray(this.geometry.convertToEWKB()),
132
                                String.valueOf(getSRSId(this.projection)),
133
                                custom(spatialType)
134
                        );
135
                    case NATIVE:
136
                    case WKB:
137
                        return MessageFormat.format(
138
                                config.getString(MSSQLServerSQLConfig.ST_GeomFromWKBEx),
139
                                bytearray(this.geometry.convertToWKB()),
140
                                String.valueOf(getSRSId(this.projection)),
141
                                custom(spatialType)
142
                        );
143
                    case WKT:
144
                    default:
145
                        return MessageFormat.format(
146
                                config.getString(MSSQLServerSQLConfig.ST_GeomFromTextEx),
147
                                string(this.geometry.convertToWKT()),
148
                                String.valueOf(getSRSId(this.projection)),
149
                                custom(spatialType)
150
                        );                        
151
                }
152
            } catch (Exception ex) {
153
                throw new RuntimeException("Can't convert geometry to string.",ex);
154
            }
155
        }
156
    }
157

    
158
    protected class MSSQLServerSelectBuilder extends SelectBuilderBase {
159

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

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

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

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

    
207
            if (this.has_offset()) {
208
                // Require SQLSeerver >= 2012
209
                builder.append(" OFFSET ");
210
                builder.append(this.offset);
211
                builder.append(" ROWS");
212
                if( this.has_limit() ) {
213
                    builder.append(" FETCH NEXT ");
214
                    builder.append(this.limit);
215
                    builder.append(" ROWS ONLY ");
216
                }
217
            }
218
            return builder.toString();
219
        }
220
    }
221

    
222
    protected class MSSQLServerCreateTableBuilder extends CreateTableBuilderBase {
223

    
224
        @Override
225
        public List<String> toStrings() {
226
            //
227
            // Respecto al base cambia la declaracion de campo automaticos
228
            // SQLServer usa IDENTITY en lugar de SERIAL.
229
            //
230
            List<String> sqls = new ArrayList<>();
231
            StringBuilder builder = new StringBuilder();
232

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

    
275
            return sqls;
276
        }
277
    }
278

    
279
    @Override
280
    protected SelectBuilder createSelectBuilder() {
281
        return new MSSQLServerSelectBuilder();
282
    }
283

    
284
    @Override
285
    protected CreateTableBuilder createCreateTableBuilder() {
286
        return new MSSQLServerCreateTableBuilder();
287
    }
288

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

    
306
    @Override
307
    public GeometryValue geometry(Geometry geom, IProjection projection) {
308
        return new MSSQLServerGeometryValue(geom, projection);
309
    }
310

    
311
    @Override
312
    public Parameter parameter() {
313
        return new MSSQLServerParameter();
314
    }
315
    
316
    @Override
317
    public Function ST_ExtentAggregate(Value geom) {
318
        String spatialType = getHelper().getSpatialType();
319
        return function("ST_ExtentAggregate", 
320
                config.getString(MSSQLServerSQLConfig.ST_ExtentAggregateEx), 
321
                geom,
322
                custom(spatialType)
323
        );
324
    }
325

    
326
    @Override
327
    public Function ST_UnionAggregate(Value geom) {
328
        String spatialType = getHelper().getSpatialType();
329
        return function("ST_UnionAggregate", 
330
                config.getString(MSSQLServerSQLConfig.ST_UnionAggregateEx), 
331
                geom,
332
                custom(spatialType)
333
        );
334
    }
335

    
336
    @Override
337
    public Function ST_GeomFromText(Value geom, Value crs) {
338
        String spatialType = getHelper().getSpatialType();
339
        return function("ST_GeomFromText", 
340
                config.getString(MSSQLServerSQLConfig.ST_GeomFromTextEx), 
341
                geom, 
342
                crs,
343
                custom(spatialType)
344
        );
345
    }
346

    
347
    @Override
348
    public Function ST_GeomFromWKB(Value geom, Value crs) {
349
        String spatialType = getHelper().getSpatialType();
350
        return function("ST_GeomFromWKB", 
351
                config.getString(MSSQLServerSQLConfig.ST_GeomFromWKBEx), 
352
                geom, 
353
                crs,
354
                custom(spatialType)
355
        );
356
    }
357

    
358
    @Override
359
    public Function ST_GeomFromEWKB(Value geom, Value crs) {
360
        String spatialType = getHelper().getSpatialType();
361
        return function("ST_GeomFromEWKB", 
362
                config.getString(MSSQLServerSQLConfig.ST_GeomFromEWKBEx), 
363
                geom, 
364
                crs,
365
                custom(spatialType)
366
        );
367
    }
368

    
369
}