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 43020 jjdelcerro
/**
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 43026 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureQueryOrder.FeatureQueryOrderMember;
36 43020 jjdelcerro
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 44058 jjdelcerro
    final static protected Logger LOGGER = LoggerFactory.getLogger(JDBCSetProvider.class);
59 43020 jjdelcerro
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 43026 jjdelcerro
        for( FeatureQueryOrderMember member : query.getOrder().members() ) {
207
            if (member.hasEvaluator()) {
208
                String sql = member.getEvaluator().getSQL();
209 43020 jjdelcerro
                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 44058 jjdelcerro
                    this.getOperations().createTableReference(params),
252 43020 jjdelcerro
                    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 44058 jjdelcerro
                TableIsEmptyOperation isEmpty_ = this.getOperations().createTableIsEmpty(
271
                        this.getOperations().createTableReference(params),
272 43020 jjdelcerro
                        params.getBaseFilter(),
273
                        filtersql
274
                );
275 44058 jjdelcerro
                this.isEmpty = (Boolean) isEmpty_.perform();
276 43020 jjdelcerro
            } else {
277
                this.isEmpty = (this.size < 1);
278
            }
279
        }
280
        return isEmpty;
281
    }
282
283 43358 jjdelcerro
284
    protected JDBCIterator createFastIterator(long index) throws DataException {
285
        return createFastIterator(index, 0);
286
    }
287
288 43020 jjdelcerro
    @Override
289 43358 jjdelcerro
    protected JDBCIterator createFastIterator(long index, long elements) throws DataException {
290 43020 jjdelcerro
        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 44058 jjdelcerro
                    this.getOperations().createTableReference(params),
301 43020 jjdelcerro
                    params.getBaseFilter(),
302
                    params.getBaseOrder(),
303
                    this.getQuery(),
304
                    storeType,
305
                    this.getFeatureType(),
306 43358 jjdelcerro
                    elements,
307 43020 jjdelcerro
                    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 43358 jjdelcerro
        return createIterator(index, -1);
325
    }
326
327
    @Override
328
    protected JDBCIterator createIterator(long index, long elements) throws DataException {
329 43020 jjdelcerro
        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 44058 jjdelcerro
                    this.getOperations().createTableReference(params),
339 43020 jjdelcerro
                    params.getBaseFilter(),
340
                    params.getBaseOrder(),
341
                    this.getQuery(),
342
                    storeType,
343
                    this.getFeatureType(),
344 43358 jjdelcerro
                    elements,
345 43020 jjdelcerro
                    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
}