Statistics
| Revision:

gvsig-mssqlserver / trunk / org.gvsig.mssqlserver / org.gvsig.mssqlserver.provider / src / main / java / org / gvsig / mssqlserver / dal / MSSQLServerHelper.java @ 25

History | View | Annotate | Download (11 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 MSSQLServerHelper extends JDBCHelperBase {
49

    
50
    private static final Logger logger = LoggerFactory.getLogger(MSSQLServerHelper.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(params.getUrl());
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 MSSQLServerHelper(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(this.getConnectionParameters());
146
            }
147
            return this.connectionProvider.getConnection();
148
        } catch (SQLException ex) {
149
            throw new AccessResourceException(MSSQLServerLibrary.NAME, ex);
150
        }
151
    }
152
    
153
    @Override
154
    public String getConnectionURL() {
155
        return getConnectionURL(this.getConnectionParameters());
156
    }
157

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

    
163
    @Override
164
    public String getProviderName() {
165
        return MSSQLServerLibrary.NAME;
166
    }
167

    
168
    @Override
169
    public JDBCSQLBuilderBase createSQLBuilder() {
170
        return new MSSQLServerSQLBuilder(this);
171
    }
172

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

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

    
258
    @Override
259
    public SQLBuilder.GeometrySupportType getGeometrySupportType() {
260
        return SQLBuilder.GeometrySupportType.WKB;
261
    }
262

    
263
    @Override
264
    public boolean hasSpatialFunctions() {
265
        return true;
266
    }
267

    
268
    @Override
269
    public boolean canWriteGeometry(int geometryType, int geometrySubtype) {
270
        return true;
271
    }
272

    
273
    @Override
274
    public String getQuoteForIdentifiers() {
275
        return "\"";
276
    }
277

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

    
283
    @Override
284
    public boolean supportOffsetInSelect() {
285
        return true;
286
    }
287

    
288
    @Override
289
    public String getQuoteForStrings() {
290
        return "'";
291
    }
292

    
293
    @Override
294
    public int getSRSCode(IProjection crs) {
295
        // TODO: ir a buscarlo a la BBDD a ver donde puede estar
296
        return super.getSRSCode(crs);
297
    }
298

    
299
    @Override
300
    public String getSourceId(JDBCStoreParameters parameters) {
301
        return parameters.getHost() + ":" +
302
               parameters.getDynValue("InstanceName")+ ":" + 
303
               parameters.getDBName() + "." + 
304
               parameters.getSchema()+ "." + 
305
               parameters.getTable();
306
    }
307

    
308
    @Override
309
    public JDBCNewStoreParameters createNewStoreParameters() {
310
        return new MSSQLServerNewStoreParameters();
311
    }
312

    
313
    @Override
314
    public JDBCStoreParameters createOpenStoreParameters() {
315
        return new MSSQLServerStoreParameters();
316
    }
317

    
318
    @Override
319
    public JDBCServerExplorerParameters createServerExplorerParameters() {
320
        return new MSSQLServerExplorerParameters();
321
    }
322

    
323
}