Statistics
| Revision:

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

History | View | Annotate | Download (13.7 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_IsClosed, "({0}).STIsClosed()");
50
        config.set(SQLConfig.ST_Overlaps, "({0}).STOverlaps({1})");
51
        config.set(SQLConfig.ST_Touches, "({0}).STTouches({1})");
52
        config.set(SQLConfig.ST_Within, "({0}).STWithin ({1})");
53
        config.set(SQLConfig.ST_Envelope, "({0}).STEnvelope()");
54
        config.set(SQLConfig.ST_Intersects, "({0}).STIntersects({1})");
55
        config.set(SQLConfig.ST_GeomFromText, "geometry::STGeomFromText({0}, {1})");
56
        config.set(SQLConfig.ST_GeomFromWKB, "geometry::STGeomFromWKB({0}, {1})");
57
        config.set(SQLConfig.ST_GeomFromEWKB, "geometry::STGeomFromWKB({0}, {1})");
58
        config.set(SQLConfig.lcase, "LOWER({0})");
59
        config.set(SQLConfig.ucase, "UPPER({0})");
60
        config.set(SQLConfig.operator_ILIKE, "LOWER({0}) LIKE LOWER({1})");
61

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

    
68
    }
69

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

    
75
    public class MSSQLServerParameter extends ParameterBase {
76

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

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

    
154
    protected class MSSQLServerSelectBuilder extends SelectBuilderBase {
155

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

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

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

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

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

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

    
214
    protected class MSSQLServerCreateTableBuilder extends CreateTableBuilderBase {
215

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

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

    
267
            return sqls;
268
        }
269
    }
270

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

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

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

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

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

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

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

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

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

    
361
}