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 / jdbc / JDBCSetProvider.java @ 40435

History | View | Annotate | Download (10.5 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 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 2
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

    
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2009 IVER T.I   {{Task}}
26
*/
27

    
28
/**
29
 *
30
 */
31
package org.gvsig.fmap.dal.store.jdbc;
32

    
33
import java.util.ArrayList;
34
import java.util.Arrays;
35
import java.util.Iterator;
36
import java.util.List;
37
import java.util.NoSuchElementException;
38

    
39
import org.gvsig.fmap.dal.DataTypes;
40
import org.gvsig.fmap.dal.exception.DataException;
41
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
42
import org.gvsig.fmap.dal.feature.FeatureQuery;
43
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
44
import org.gvsig.fmap.dal.feature.FeatureType;
45
import org.gvsig.fmap.dal.feature.FeatureQueryOrder.FeatureQueryOrderMember;
46
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureSetProvider;
47
import org.gvsig.tools.evaluator.Evaluator;
48
import org.gvsig.tools.evaluator.EvaluatorFieldValue;
49
import org.gvsig.tools.evaluator.EvaluatorFieldsInfo;
50
import org.gvsig.tools.exception.BaseException;
51
import org.slf4j.Logger;
52
import org.slf4j.LoggerFactory;
53

    
54
/**
55
 * @author jmvivo
56
 *
57
 */
58
public class JDBCSetProvider extends AbstractFeatureSetProvider {
59

    
60
        final static private Logger logger = LoggerFactory
61
                        .getLogger(JDBCSetProvider.class);
62

    
63
        protected String filter;
64
        protected String order;
65
        protected Long size = null;
66
        protected Boolean isEmpty = null;
67

    
68
        protected List resultSetIDReferenced;
69

    
70
        private JDBCHelper helper = null;
71

    
72
        private int defaultFetchSize = 1000;
73

    
74
        private long limit = -1l;
75

    
76
    private boolean directSQLMode;
77

    
78
        public JDBCSetProvider(JDBCStoreProvider store, FeatureQuery query,
79
                        FeatureType featureType) throws DataException {
80
                super(store, query, featureType);
81
                this.helper = store.getHelper();
82
                this.resultSetIDReferenced = new ArrayList();
83
                this.directSQLMode =  store.isDirectSQLMode();
84
        
85
                if (query.hasFilter() && this.canFilter()) {
86
                        setFilter(query.getFilter());
87
                } else {
88
                        setFilter(null);
89
                }
90

    
91
                if (query.hasOrder() && canOrder()) {
92
                        setOrder(query.getOrder());
93
                } else {
94
                        setOrder(null);
95
                }
96

    
97
                if (query != null) {
98
                        limit = query.getLimit();
99
                }
100
        }
101

    
102
        /**
103
         * @return the defaultFetchSize
104
         */
105
        public int getDefaultFetchSize() {
106
                return defaultFetchSize;
107
        }
108

    
109
        /**
110
         * @param defaultFetchSize
111
         *            the defaultFetchSize to set
112
         */
113
        public void setDefaultFetchSize(int defaultFetchSize) {
114
                this.defaultFetchSize = defaultFetchSize;
115
        }
116

    
117
        protected String getSqlForEvaluator(Evaluator filter) {
118
                if (filter == null) {
119
                        return null;
120
                }
121
                EvaluatorFieldsInfo info = filter.getFieldsInfo();
122
                String filterString = filter.getSQL();
123
                if (info == null) {
124
                        return filterString;
125
                }
126
                String[] filterNames = info.getFieldNames();
127
                String[] finalNames = new String[filterNames.length];
128
                EvaluatorFieldValue[] fValues;
129

    
130
                List values = new ArrayList();
131

    
132
                FeatureAttributeDescriptor attr;
133
                for (int i = 0; i < filterNames.length; i++) {
134
                        attr = getFeatureType().getAttributeDescriptor(filterNames[i]);
135
                        if (attr == null) {
136
                                finalNames[i] = filterNames[i];
137
                                continue;
138
                        }
139
                        finalNames[i] = getEscapedFieldName(attr.getName());
140

    
141
                }
142

    
143
                for (int i = 0; i < filterNames.length; i++) {
144
                        if (!filterNames[i].equals(finalNames[i])) {
145
                                filterString.replaceAll("\\b" + filterNames[i] + "\\b",
146
                                                finalNames[i]);
147
                        }
148
                }
149

    
150
                return filterString;
151
        }
152

    
153

    
154
        protected String getEscapedFieldName(String fieldName) {
155
                if (helper == null) {
156
                        helper = getJDBCStoreProvider().getHelper();
157
                }
158
                return helper.escapeFieldName(fieldName);
159
        }
160

    
161

    
162
        protected void setOrder(FeatureQueryOrder order) {
163
                if (order == null || order.size() == 0) {
164
                        this.order = null;
165
                        return;
166
                }
167

    
168
                StringBuilder buffer = new StringBuilder();
169
                Iterator iter = order.iterator();
170
                FeatureQueryOrderMember menber;
171
                while (true) {
172
                        menber = (FeatureQueryOrderMember) iter.next();
173
                        if (menber.hasEvaluator()) {
174
                                buffer.append(getSqlForEvaluator(menber.getEvaluator()));
175
                        } else {
176
                                buffer.append(getEscapedFieldName(menber.getAttributeName()));
177
                        }
178
                        if (menber.getAscending()) {
179
                                buffer.append(" ASC");
180
                        } else {
181
                                buffer.append(" DESC");
182
                        }
183
                        if (iter.hasNext()) {
184
                                buffer.append(", ");
185
                        } else {
186
                                buffer.append(' ');
187
                                break;
188
                        }
189
                }
190

    
191
                this.order = buffer.toString();
192
        }
193

    
194
        protected void setFilter(Evaluator filter) {
195
                this.filter = getSqlForEvaluator(filter);
196
        }
197

    
198

    
199

    
200
        /* (non-Javadoc)
201
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#canFilter()
202
         */
203
        public boolean canFilter() {
204
                Evaluator filter = getQuery().getFilter();
205
                if (directSQLMode){
206
                    return false;
207
                }
208
                if (filter != null) {
209
                        if (filter.getSQL() == null || filter.getSQL().length() == 0) {
210
                                return false;
211
                        } else {
212
                                // TODO Check Geom fields if
213
                                EvaluatorFieldsInfo fInfo = filter.getFieldsInfo();
214
                                if (fInfo == null || fInfo.getFieldNames() == null) {
215
                                        return true;
216
                                }
217
                                Iterator names = Arrays.asList(fInfo.getFieldNames())
218
                                                .iterator();
219
                                String name;
220
                                int type;
221
                                while (names.hasNext()) {
222
                                        name = (String) names.next();
223
                                        type =
224
                                                        this.getFeatureType()
225
                                                                        .getAttributeDescriptor(name)
226
                                                        .getType();
227
                                        if (type == DataTypes.GEOMETRY
228
                                                        && !this.helper.supportsGeometry()) {
229
                                                return false;
230
                                        }
231

    
232

    
233

    
234
                                }
235

    
236
                                return true;
237
                        }
238

    
239
                } else{
240
                        return false;
241
                }
242
        }
243

    
244
        /* (non-Javadoc)
245
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#canIterateFromIndex()
246
         */
247
        public boolean canIterateFromIndex() {
248
                return helper.supportOffset();
249
        }
250

    
251
        /* (non-Javadoc)
252
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#canOrder()
253
         */
254
        public boolean canOrder() {
255
            if (directSQLMode){
256
                return false;
257
            }
258
                // TODO Check Geom fields if postgis not are available
259
                FeatureQuery query = getQuery();
260
                if (query.hasOrder()) {
261
                        Iterator iter = query.getOrder().iterator();
262
                        FeatureQueryOrderMember menber;
263
                        String sql;
264
                        while (iter.hasNext()){
265
                                menber = (FeatureQueryOrderMember) iter.next();
266
                                if (menber.hasEvaluator()){
267
                                        sql = menber.getEvaluator().getSQL();
268
                                        if (sql == null || sql.length() == 0) {
269
                                                return false;
270
                                        }
271
                                }
272
                        }
273
                }
274
                return true;
275
        }
276

    
277
        private JDBCStoreProvider getJDBCStoreProvider() {
278
                return (JDBCStoreProvider) getStore();
279
        }
280

    
281
        @Override
282
        protected void doDispose() throws BaseException {
283
                if (resultSetIDReferenced != null) {
284
                        Iterator iter = resultSetIDReferenced.iterator();
285
                        Integer resID;
286
                        while (iter.hasNext()) {
287
                                resID = (Integer) iter.next();
288
                                if (resID != null) {
289
                                        logger.warn(
290
                                                "ResultSet (ID {}) not closed on dispose, will close",
291
                                                resID);
292
                                        try {
293
                                                getJDBCStoreProvider().closeResulset(resID.intValue());
294
                                        } catch (DataException e) {
295
                                                logger.error("Close resulset Exception", e);
296
                                        }
297
                                }
298
                                iter.remove();
299
                        }
300
                }
301
                resultSetIDReferenced = null;
302
                filter = null;
303
                order = null;
304
                size = null;
305
                isEmpty = null;
306
        }
307

    
308
        protected String getSQL(long fromIndex) throws DataException {
309
                return getJDBCStoreProvider().compoundSelect(getFeatureType(), filter,
310
                                order, limit, fromIndex);
311

    
312
        }
313

    
314
        /* (non-Javadoc)
315
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#getSize()
316
         */
317
        public long getSize() throws DataException {
318
                if (size == null) {
319
                        size = new Long(getJDBCStoreProvider().getCount(filter));
320
                }
321
                return size.longValue();
322
        }
323

    
324
        /* (non-Javadoc)
325
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#isEmpty()
326
         */
327
        public boolean isEmpty() throws DataException {
328
                JDBCStoreProvider store = getJDBCStoreProvider();
329
                if (isEmpty == null) {
330
                        if (size == null) {
331
                                String sql =
332
                                                store.compoundSelect(getFeatureType(), filter, null, 1,
333
                                                                0);
334
                                int rsID = store.createResultSet(sql, getFetchSize());
335
                                isEmpty = new Boolean(!store.resulsetNext(rsID));
336
                                store.closeResulset(rsID);
337
                        } else {
338
                                isEmpty = new Boolean(size.longValue() < 1);
339
                        }
340
                }
341
                return isEmpty.booleanValue();
342
        }
343

    
344
        protected int getFetchSize() {
345
                long pageSize = -1;
346
                if (getQuery() != null) {
347
                        pageSize = getQuery().getPageSize();
348
                        pageSize =
349
                                        pageSize > Integer.MAX_VALUE ? Integer.MAX_VALUE : pageSize;
350
                }
351
                return (pageSize > 0 ? (int) pageSize : defaultFetchSize);
352
        }
353

    
354
        protected JDBCIterator createFastIterator(long index) throws DataException {
355
                if (isEmpty != null && isEmpty.booleanValue()) {
356
                        return new EmptyJDBCIterator(getJDBCStoreProvider());
357
                }
358
                int rsID =
359
                                getJDBCStoreProvider().createResultSet(getSQL(index),
360
                                                getFetchSize());
361
                return createDefaultFastIterator(rsID);
362
        }
363

    
364
        protected JDBCIterator createDefaultFastIterator(int resultSetID)
365
                        throws DataException {
366
                return new JDBCFastIterator(getJDBCStoreProvider(), this,
367
                                getFeatureType(), resultSetID);
368
        }
369

    
370
        protected JDBCIterator createIterator(long index) throws DataException {
371
        if (isEmpty != null && isEmpty.booleanValue()) {
372
            return new EmptyJDBCIterator(getJDBCStoreProvider());
373
        }
374
        int rsID =
375
                getJDBCStoreProvider().createResultSet(getSQL(index),
376
                        getFetchSize());
377
        return createDefaultIterator(rsID);
378
        }
379

    
380
        protected JDBCIterator createDefaultIterator(int resultSetID)
381
                        throws DataException {
382
                return new JDBCIterator(getJDBCStoreProvider(), this, getFeatureType(),
383
                                resultSetID);
384
        }
385

    
386
        public void addResulsetReference(int resulsetID) {
387
                this.resultSetIDReferenced.add(new Integer(resulsetID));
388
        }
389

    
390
        public void removeResulsetReference(int resulsetID) {
391
                this.resultSetIDReferenced.remove(new Integer(resulsetID));
392
        }
393

    
394
        private class EmptyJDBCIterator extends JDBCIterator {
395

    
396
                protected EmptyJDBCIterator(JDBCStoreProvider store) throws DataException {
397
                        super(store, null, null, -1);
398
                }
399

    
400
                @Override
401
                protected boolean internalHasNext() {
402
                        return false;
403
                }
404

    
405
                @Override
406
                protected Object internalNext() {
407
                        throw new NoSuchElementException();
408
                }
409

    
410
                @Override
411
                protected void doDispose() throws BaseException {
412
                        // nothing to do
413
                }
414

    
415
        }
416

    
417
}