Statistics
| Revision:

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

History | View | Annotate | Download (10.9 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2016 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 3
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
package org.gvsig.mssqlserver.dal;
23

    
24
import org.gvsig.mssqlserver.dal.operations.MSSQLServerOperationsFactory;
25
import java.sql.Connection;
26
import java.sql.SQLException;
27
import java.text.MessageFormat;
28
import org.apache.commons.dbcp.BasicDataSource;
29
import org.apache.commons.lang3.StringUtils;
30
import org.cresques.cts.IProjection;
31
import org.gvsig.fmap.dal.DataParameters;
32
import org.gvsig.fmap.dal.DataTypes;
33
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
34
import org.gvsig.fmap.dal.feature.FeatureType;
35
import org.gvsig.fmap.dal.SQLBuilder;
36
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
37
import org.gvsig.fmap.dal.store.jdbc.JDBCConnectionParameters;
38
import org.gvsig.fmap.dal.store.jdbc.JDBCNewStoreParameters;
39
import org.gvsig.fmap.dal.store.jdbc.JDBCServerExplorerParameters;
40
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
41
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCDriverClassNotFoundException;
42
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory;
43
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCHelperBase;
44
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
45
import org.slf4j.Logger;
46
import org.slf4j.LoggerFactory;
47

    
48
public class MSSQLServerSQLHelper extends JDBCHelperBase {
49

    
50
    private static final Logger logger = LoggerFactory.getLogger(MSSQLServerSQLHelper.class);
51

    
52
    public static final String NAME = "MSSQLServer";
53
    public static final String INSTANCE_NAME = "SQLEXPRESS";
54
    public static final int PORT = 1433;
55
    public static final String MSSQLServerJDBCDriver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
56
    
57
//    private static final boolean ALLOW_AUTOMATIC_VALUES = true;
58
//    private static final String QUOTE_FOR_USE_IN_IDENTIFIERS = "\"";
59
//    private static final String QUOTE_FOR_USE_IN_STRINGS = "'";
60

    
61
    public static String getConnectionURL(JDBCConnectionParameters params) {
62
        String connectionURL = MessageFormat.format(
63
                //"jdbc:sqlserver://{0}:{1,number,#};databaseName={2};instanceName={3};",
64
                "jdbc:sqlserver://{0};databaseName={2};instanceName={3};",
65
                params.getHost(),
66
                params.getPort(),
67
                params.getDBName(),
68
                ((DataParameters) params).getDynValue("instanceName")
69
        );
70
        logger.debug("connectionURL: {}", connectionURL);
71
        return connectionURL;
72
    }
73

    
74
    private static class ConnectionProvider {
75

    
76
        private static boolean needRegisterDriver = true;
77

    
78
        private BasicDataSource dataSource = null;
79

    
80
        private final JDBCConnectionParameters connectionParameters;
81

    
82
        public ConnectionProvider(JDBCConnectionParameters connectionParameters) {
83
            this.connectionParameters = connectionParameters;
84
        }
85

    
86
        public Connection getConnection() throws SQLException {
87
            if (this.dataSource == null) {
88
                this.dataSource = this.createDataSource();
89
            }
90
            Connection conn = this.dataSource.getConnection();
91
            return conn;
92
        }
93

    
94
        private BasicDataSource createDataSource() throws SQLException {
95
            if (!this.isRegistered()) {
96
                this.registerDriver();
97
            }
98
            JDBCConnectionParameters params = connectionParameters;
99

    
100
            BasicDataSource dataSource = new BasicDataSource();
101
            dataSource.setDriverClassName(params.getJDBCDriverClassName());
102
            dataSource.setUsername(params.getUser());
103
            dataSource.setPassword(params.getPassword());
104
            dataSource.setUrl(getConnectionURL(params));
105

    
106
            dataSource.setMaxWait(60L * 1000);
107
            return dataSource;
108
        }
109

    
110
        private boolean isRegistered() {
111
            return needRegisterDriver;
112
        }
113

    
114
        public void registerDriver() throws SQLException {
115
            String className = this.connectionParameters.getJDBCDriverClassName();
116
            if (className == null) {
117
                return;
118
            }
119
            try {
120
                Class theClass = Class.forName(className);
121
                if (theClass == null) {
122
                    throw new JDBCDriverClassNotFoundException(MSSQLServerLibrary.NAME, className);
123
                }
124
            } catch (Exception e) {
125
                throw new SQLException("Can't register JDBC driver '" + className + "'.", e);
126
            }
127
            needRegisterDriver = false;
128
        }
129

    
130
    }
131

    
132
    private ConnectionProvider connectionProvider = null;
133

    
134
    private FeatureType lastUsedFeatureType = null;
135
    private String lastUsedSpatialType = null;
136
    
137
    public MSSQLServerSQLHelper(JDBCConnectionParameters connectionParameters) {
138
        super(connectionParameters);
139
    }
140

    
141
    @Override
142
    public Connection getConnection() throws AccessResourceException {
143
        try {
144
            if (this.connectionProvider == null) {
145
                this.connectionProvider = new ConnectionProvider(connectionParameters);
146
            }
147
            return this.connectionProvider.getConnection();
148
        } catch (SQLException ex) {
149
            throw new AccessResourceException(MSSQLServerLibrary.NAME, ex);
150
        }
151
    }
152

    
153
    @Override
154
    protected String getResourceType() {
155
        return MSSQLServerLibrary.NAME;
156
    }
157

    
158
    @Override
159
    public String getProviderName() {
160
        return MSSQLServerLibrary.NAME;
161
    }
162

    
163
    @Override
164
    public JDBCSQLBuilderBase createSQLBuilder() {
165
        return new MSSQLServerSQLBuilder(this);
166
    }
167

    
168
    /**
169
     * Devuelbe el nombre del tipo de datos espacial de SQLServer asociado 
170
     * al ultimo FeatureType cargado.
171
     * 
172
     * Esta funcion es usada para dar un soporte limitado al tipo de datos
173
     * spaciales "geography".
174
     * 
175
     * Si no disponemos de un FeatureType asumimos "geometry".
176
     * Si hay un solo campo espacial asume el tipo de ese campo, y si 
177
     * hay mas de uno asume "geometry".
178
     * En caso de que no haya ningun campo espacial asumimos "geometry".
179
     * 
180
     * @return "geometry" or "geography" for the last used table.
181
     */
182
    public String getSpatialType() {
183
        if( this.lastUsedSpatialType != null ) {
184
            return this.lastUsedSpatialType;
185
        }
186
        if( this.lastUsedFeatureType == null ) {
187
            this.lastUsedSpatialType = "geometry";
188
            return this.lastUsedSpatialType;
189
        }
190
        String spatialType = null;
191
        for (FeatureAttributeDescriptor attr : lastUsedFeatureType) {
192
            if( attr.getType() == DataTypes.GEOMETRY ) {
193
                if( spatialType != null ) {
194
                    this.lastUsedSpatialType = "geometry";
195
                    return this.lastUsedSpatialType;
196
                }
197
                spatialType = (String) attr.getAdditionalInfo("SQLServer_type_name");
198
            }
199
        }
200
        if( StringUtils.isEmpty(spatialType) ) {
201
            this.lastUsedSpatialType = "geometry";
202
            return this.lastUsedSpatialType;
203
        }
204
        this.lastUsedSpatialType = spatialType;
205
        return this.lastUsedSpatialType;
206
    }
207

    
208
    /**
209
     * Devuelbe el tipo de datos espacial de SQLServer asociado a la columna 
210
     * indicada.
211
     * 
212
     * Esta funcion es usada para dar un soporte limitado al tipo de datos
213
     * spaciales "geography".
214
     * 
215
     * Si no disponemos de un FeatureType asumimos "geometry".
216
     * Si no existe el campo solicitado o no es de tipo geoemtria, asumimos 
217
     * el tipo espacia asociado al FeatureType (getSpatialType()).
218
     * 
219
     * @param columnName
220
     * @return "geometry" or "geography" for column in the last used table.
221
     */
222
    public String getSpatialType(String columnName) {
223
        if( this.lastUsedFeatureType == null ) {
224
            return "geometry";
225
        }
226
        FeatureAttributeDescriptor attr = this.lastUsedFeatureType.getAttributeDescriptor(columnName);
227
        if( attr == null ) {
228
            return this.getSpatialType();
229
        }
230
        if( attr.getType() != DataTypes.GEOMETRY ) {
231
            return this.getSpatialType();
232
        }
233
        String spatialType = (String) attr.getAdditionalInfo("SQLServer_type_name");
234
        if( StringUtils.isEmpty(spatialType) ) {
235
            return "geometry";
236
        }
237
        return spatialType;
238
    }
239
    
240
    public void setLastUsedFeatureType(FeatureType featureType) {
241
        this.lastUsedSpatialType = null;
242
        this.lastUsedFeatureType = featureType;
243
    }
244
    
245
    @Override
246
    public OperationsFactory getOperations() {
247
        if (this.operationsFactory == null) {
248
            this.operationsFactory = new MSSQLServerOperationsFactory(this);
249
        }
250
        return operationsFactory;
251
    }
252

    
253
    @Override
254
    public SQLBuilder.GeometrySupportType getGeometrySupportType() {
255
        return SQLBuilder.GeometrySupportType.WKB;
256
    }
257

    
258
    @Override
259
    public boolean hasSpatialFunctions() {
260
        return true;
261
    }
262

    
263
    @Override
264
    public boolean canWriteGeometry(int geometryType, int geometrySubtype) {
265
        return true;
266
    }
267

    
268
    @Override
269
    public String getQuoteForIdentifiers() {
270
        return "\"";
271
    }
272

    
273
    @Override
274
    public boolean allowAutomaticValues() {
275
        return true;
276
    }
277

    
278
    @Override
279
    public boolean supportOffsetInSelect() {
280
        return true;
281
    }
282

    
283
    @Override
284
    public String getQuoteForStrings() {
285
        return "'";
286
    }
287

    
288
    @Override
289
    public int getSRSCode(IProjection crs) {
290
        // TODO: ir a buscarlo a la BBDD a ver donde puede estar
291
        return super.getSRSCode(crs);
292
    }
293

    
294
    @Override
295
    public String getSourceId(JDBCStoreParameters parameters) {
296
        return parameters.getHost() + ":" +
297
               parameters.getDynValue("InstanceName")+ ":" + 
298
               parameters.getDBName() + "." + 
299
               parameters.getSchema()+ "." + 
300
               parameters.getTable();
301
    }
302

    
303
    @Override
304
    public JDBCNewStoreParameters createNewStoreParameters() {
305
        return new MSSQLServerNewStoreParameters();
306
    }
307

    
308
    @Override
309
    public JDBCStoreParameters createOpenStoreParameters() {
310
        return new MSSQLServerStoreParameters();
311
    }
312

    
313
    @Override
314
    public JDBCServerExplorerParameters createServerExplorerParameters() {
315
        return new MSSQLServerExplorerParameters();
316
    }
317

    
318
}