Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.db / org.gvsig.fmap.dal.db.jdbc / src / main / java / org / gvsig / fmap / dal / store / jdbc2 / impl / JDBCSetProvider.java @ 44058

History | View | Annotate | Download (12.1 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.dal.store.jdbc2.impl;
24

    
25
import java.util.ArrayList;
26
import java.util.List;
27
import java.util.NoSuchElementException;
28
import org.apache.commons.collections.CollectionUtils;
29
import org.apache.commons.lang3.BooleanUtils;
30
import org.apache.commons.lang3.StringUtils;
31

    
32
import org.gvsig.fmap.dal.DataTypes;
33
import org.gvsig.fmap.dal.exception.DataException;
34
import org.gvsig.fmap.dal.feature.FeatureQuery;
35
import org.gvsig.fmap.dal.feature.FeatureQueryOrder.FeatureQueryOrderMember;
36
import org.gvsig.fmap.dal.feature.FeatureType;
37

    
38
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureSetProvider;
39
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
40
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
41
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
42
import org.gvsig.fmap.dal.store.jdbc2.JDBCStoreProvider;
43
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
44
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory;
45
import org.gvsig.fmap.dal.store.jdbc2.ResulSetControler;
46
import org.gvsig.fmap.dal.store.jdbc2.ResulSetControler.ResultSetEntry;
47
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.TableIsEmptyOperation;
48
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.ResultSetForSetProviderOperation;
49
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.CountOperation;
50
import org.gvsig.tools.evaluator.Evaluator;
51
import org.gvsig.tools.evaluator.EvaluatorFieldsInfo;
52
import org.gvsig.tools.exception.BaseException;
53
import org.slf4j.Logger;
54
import org.slf4j.LoggerFactory;
55

    
56
public class JDBCSetProvider extends AbstractFeatureSetProvider {
57

    
58
    final static protected Logger LOGGER = LoggerFactory.getLogger(JDBCSetProvider.class);
59

    
60
    private class EmptyJDBCIterator extends JDBCIterator {
61

    
62
        protected EmptyJDBCIterator(JDBCStoreProvider store) throws DataException {
63
            super(store, null, null, null);
64
        }
65

    
66
        @Override
67
        protected boolean internalHasNext() {
68
            return false;
69
        }
70

    
71
        @Override
72
        protected Object internalNext() {
73
            throw new NoSuchElementException();
74
        }
75

    
76
        @Override
77
        protected void doDispose() throws BaseException {
78
            // nothing to do
79
        }
80

    
81
    }
82

    
83
    
84
    protected Long size = null;
85
    protected Boolean isEmpty = null;
86
    protected List<ResultSetEntry> resultSets;
87
    private int defaultFetchSize = 1000;
88

    
89
    public JDBCSetProvider(
90
            AbstractFeatureStoreProvider store,
91
            JDBCHelper helper,
92
            FeatureQuery query,
93
            FeatureType featureType
94
    ) throws DataException {
95
        super(store, query, featureType);
96
        this.resultSets = new ArrayList<>();
97
    }
98

    
99
    /**
100
     * @return the defaultFetchSize
101
     */
102
    public int getDefaultFetchSize() {
103
        return defaultFetchSize;
104
    }
105

    
106
    /**
107
     * @param defaultFetchSize the defaultFetchSize to set
108
     */
109
    public void setDefaultFetchSize(int defaultFetchSize) {
110
        this.defaultFetchSize = defaultFetchSize;
111
    }
112

    
113
//    @Override
114
//    protected JDBCStoreProvider getStore() {
115
//        return (JDBCStoreProvider) super.getStore();
116
//    }
117

    
118
    protected JDBCStoreProvider getJDBCStore() {
119
//        Corregido el problema en AbstractFeatureSetProvider, de que getStore
120
//        debe ser un FeatureStoreProvider y no un AbstractFeatureStoreProvider
121
//        este metodo debe desaparecer y quedar el getStore de arriba que esta
122
//          comentarizado
123
        return (JDBCStoreProvider) super.getStore();
124
    }    
125
    
126
    protected JDBCHelper getHelper() {
127
        return this.getJDBCStore().getHelper();
128
    }
129
    
130
    protected OperationsFactory getOperations() {
131
        return this.getHelper().getOperations();
132
    }
133

    
134
    @Override
135
    public boolean canIterateFromIndex() {
136
        return this.getHelper().supportOffsetInSelect();
137
    }
138
    
139
    @Override
140
    public boolean canFilter() {
141
        // No podemos filtrar si:
142
        // - Hay una subquery especificada en los parametros 
143
        // - Si no soportamos geometrias y hay un filtro espacial.
144
        //
145
        if (this.getHelper().useSubquery()) {
146
            return false;
147
        }
148
        if( this.getHelper().hasSpatialFunctions() ) {
149
            // Como soportamos filtros espaciales, podremos hacer cualquier
150
            // filtro que se especifique, sea alfanumerico o espacial.
151
            return true;
152
        }
153
        
154
        // No se soportan filtros espaciales.
155
        // Si se esta filtrando por un campo Geometria, retornamos false
156
        
157
        Evaluator filter = getQuery().getFilter();
158
        if (filter == null) {
159
            return true;
160
        }
161
        
162
        String sql = filter.getSQL();
163
        if (StringUtils.isEmpty(sql)) {
164
            return true;
165
        }
166

    
167
        EvaluatorFieldsInfo fInfo = filter.getFieldsInfo();
168
        if (fInfo == null ) {
169
            return true;
170
        }
171
        String[] names = fInfo.getFieldNames();
172
        if (  names == null) {
173
            return true;
174
        }
175
        
176
        for (String name : names) {
177
            int type = this.getFeatureType()
178
                .getAttributeDescriptor(name)
179
                .getType();
180
            if( type == DataTypes.GEOMETRY ) {
181
                return false;
182
            }
183
        }
184
        return true;
185
    }
186

    
187
    @Override
188
    public boolean canOrder() {
189
        // No podemos ordenar si:
190
        // - Hay una subquery especificada en los parametros 
191
        // - Si no soportamos geometrias y hay un filtro espacial.
192
        //
193
        if (this.getHelper().useSubquery()) {
194
            return false;
195
        }
196
        if( this.getHelper().hasSpatialFunctions() ) {
197
            // Como soportamos filtros espaciales, podremos hacer cualquier
198
            // filtro que se especifique, sea alfanumerico o espacial.
199
            return true;
200
        }
201

    
202
        FeatureQuery query = getQuery();
203
        if (!query.hasOrder()) {
204
            return true;
205
        }
206
        for( FeatureQueryOrderMember member : query.getOrder().members() ) {
207
            if (member.hasEvaluator()) {
208
                String sql = member.getEvaluator().getSQL();
209
                if ( StringUtils.isEmpty(sql) ) {
210
                    return false;
211
                }
212
            }            
213
        }
214
        return true;
215
    }
216
    
217
    public ResulSetControler getResulSetControler() {
218
        return this.getHelper().getResulSetControler();
219
    }
220

    
221
    @Override
222
    protected void doDispose() throws BaseException {
223
        if( ! CollectionUtils.isEmpty(this.resultSets) ) {
224
            for( ResultSetEntry resulset : this.resultSets ) {
225
               JDBCUtils.closeQuietly(resulset);
226
            }
227
        }
228
        size = null;
229
        isEmpty = null;
230
    }
231

    
232
    protected int getFetchSize() {
233
        long pageSize = -1;
234
        if (getQuery() != null) {
235
            pageSize = getQuery().getPageSize();
236
            pageSize = pageSize > Integer.MAX_VALUE ? Integer.MAX_VALUE : pageSize;
237
        }
238
        return (pageSize > 0 ? (int) pageSize : defaultFetchSize);
239
    }
240

    
241
    @Override
242
    public long getSize() throws DataException {
243
        if (size == null) {
244
            JDBCStoreParameters params = this.getJDBCStore().getParameters();
245
            String filtersql = null;
246
            Evaluator filter = this.getQuery().getFilter();
247
            if( filter != null ) {
248
                filtersql = filter.getSQL();
249
            }
250
            CountOperation selectCount = this.getOperations().createCount(
251
                    this.getOperations().createTableReference(params),
252
                    params.getBaseFilter(), 
253
                    filtersql
254
            );
255
            size = (Long) selectCount.perform();              
256
        }
257
        return size;
258
    }
259

    
260
    @Override
261
    public boolean isEmpty() throws DataException {
262
        if (this.isEmpty == null) {
263
            if (this.size == null) {
264
                JDBCStoreParameters params = this.getJDBCStore().getParameters();
265
                String filtersql = null;
266
                Evaluator filter = this.getQuery().getFilter();
267
                if( filter != null ) {
268
                    filtersql = filter.getSQL();
269
                }
270
                TableIsEmptyOperation isEmpty_ = this.getOperations().createTableIsEmpty(
271
                        this.getOperations().createTableReference(params),
272
                        params.getBaseFilter(), 
273
                        filtersql
274
                );
275
                this.isEmpty = (Boolean) isEmpty_.perform();   
276
            } else {
277
                this.isEmpty = (this.size < 1);
278
            }
279
        }
280
        return isEmpty;
281
    }
282

    
283

    
284
    protected JDBCIterator createFastIterator(long index) throws DataException {
285
        return createFastIterator(index, 0);
286
    }
287
    
288
    @Override
289
    protected JDBCIterator createFastIterator(long index, long elements) throws DataException {
290
        if( BooleanUtils.isTrue(isEmpty) ) {
291
            return new EmptyJDBCIterator(this.getJDBCStore());
292
        }
293
        
294
        JDBCStoreParameters params = this.getJDBCStore().getParameters();
295
        FeatureType storeType = this.getStore()
296
                .getStoreServices()
297
                .getProviderFeatureType(this.getFeatureType().getId());
298
        ResultSetForSetProviderOperation createResultSet 
299
            = getOperations().createResultSetForSetProvider(
300
                    this.getOperations().createTableReference(params),
301
                    params.getBaseFilter(), 
302
                    params.getBaseOrder(), 
303
                    this.getQuery(), 
304
                    storeType, 
305
                    this.getFeatureType(), 
306
                    elements, 
307
                    index, 
308
                    this.getDefaultFetchSize()
309
            );
310

    
311
        ResultSetEntry resultSetEntry = (ResultSetEntry) createResultSet.perform();
312

    
313
        this.resultSets.add(resultSetEntry);
314
        return new JDBCFastIterator(
315
                this.getJDBCStore(), 
316
                this, 
317
                this.getFeatureType(),
318
                resultSetEntry
319
        );
320
    }
321

    
322
    @Override
323
    protected JDBCIterator createIterator(long index) throws DataException {
324
        return createIterator(index, -1);
325
    }
326
    
327
    @Override
328
    protected JDBCIterator createIterator(long index, long elements) throws DataException {
329
        if( BooleanUtils.isTrue(isEmpty) ) {
330
            return new EmptyJDBCIterator(this.getJDBCStore());
331
        }
332
        JDBCStoreParameters params = this.getJDBCStore().getParameters();
333
        FeatureType storeType = this.getStore()
334
                .getStoreServices()
335
                .getProviderFeatureType(this.getFeatureType().getId());
336
        ResultSetForSetProviderOperation createResultSet 
337
            = getOperations().createResultSetForSetProvider(
338
                    this.getOperations().createTableReference(params),
339
                    params.getBaseFilter(), 
340
                    params.getBaseOrder(), 
341
                    this.getQuery(), 
342
                    storeType, 
343
                    this.getFeatureType(), 
344
                    elements, 
345
                    index, 
346
                    this.getDefaultFetchSize()
347
            );
348

    
349
        ResultSetEntry resultSetEntry = (ResultSetEntry) createResultSet.perform();
350
        this.resultSets.add(resultSetEntry);
351
        return new JDBCIterator(
352
                this.getJDBCStore(), 
353
                this, 
354
                this.getFeatureType(),
355
                resultSetEntry
356
        );
357
    }
358

    
359
}