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 / spi / operations / CountOperation.java @ 46517

History | View | Annotate | Download (8.18 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2020 gvSIG Association.
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.dal.store.jdbc2.spi.operations;
25

    
26
import java.sql.ResultSet;
27
import java.sql.SQLException;
28
import java.sql.Statement;
29
import java.util.ArrayList;
30
import java.util.List;
31
import org.apache.commons.lang3.StringUtils;
32
import org.gvsig.expressionevaluator.ExpressionBuilder;
33
import org.gvsig.fmap.dal.SQLBuilder.SelectBuilder;
34
import org.gvsig.fmap.dal.exception.DataException;
35
import org.gvsig.fmap.dal.feature.FeatureQuery;
36
import org.gvsig.fmap.dal.feature.FeatureType;
37
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
38
import org.gvsig.fmap.dal.store.jdbc2.JDBCConnection;
39
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
40
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
41
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory.TableReference;
42
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
43
import static org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase.PROP_FEATURE_TYPE;
44
import static org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase.PROP_JDBCHELPER;
45
import static org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase.PROP_QUERY;
46
import static org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase.PROP_SYMBOLTABLE;
47
import static org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase.PROP_TABLE;
48
import static org.gvsig.fmap.dal.store.jdbc2.spi.operations.ResultSetForSetProviderOperation.getAllExtraColumns;
49
import static org.gvsig.fmap.dal.store.jdbc2.spi.operations.ResultSetForSetProviderOperation.process2_ComputedFields;
50
import static org.gvsig.fmap.dal.store.jdbc2.spi.operations.ResultSetForSetProviderOperation.process3_Where;
51
import static org.gvsig.fmap.dal.store.jdbc2.spi.operations.ResultSetForSetProviderOperation.process4_Aggregates;
52
import static org.gvsig.fmap.dal.store.jdbc2.spi.operations.ResultSetForSetProviderOperation.process5_GroupBys;
53

    
54
public class CountOperation extends AbstractConnectionOperation {
55

    
56
    private final TableReference table;
57
    private final String baseFilter;
58
    private final FeatureQuery query;
59
    private final FeatureType featureType;
60

    
61
    public CountOperation(
62
            JDBCHelper helper
63
        ) {
64
        this(helper, null, null, null, null);
65
    }
66

    
67
    public CountOperation(
68
            JDBCHelper helper,
69
            FeatureType featureType,
70
            TableReference table,
71
            String baseFilter,
72
            FeatureQuery query
73
        ) {
74
        super(helper);
75
        this.featureType = featureType;
76
        this.table = table;
77
        this.baseFilter = baseFilter;
78
        this.query = query;
79
    }
80

    
81
    @Override
82
    public final Object perform(JDBCConnection conn) throws DataException {
83
        return this.count(conn);
84
    }
85

    
86
    public String getSQL() {
87
        JDBCSQLBuilderBase sqlbuilder = this.createSQLBuilder();
88
        ExpressionBuilder expbuilder = sqlbuilder.expression();
89
        
90
        expbuilder.setProperty(PROP_FEATURE_TYPE, this.featureType);
91
        expbuilder.setProperty(PROP_TABLE, table);
92
        expbuilder.setProperty(PROP_SYMBOLTABLE, this.query==null? null:this.query.getSymbolTable());
93
        expbuilder.setProperty(PROP_JDBCHELPER, this.helper);
94
        expbuilder.setProperty(PROP_QUERY, this.query);
95

    
96
        SelectBuilder select = sqlbuilder.select();
97
        select.from().table()
98
                .database(this.table.getDatabase())
99
                .schema(this.table.getSchema())
100
                .name(this.table.getTable());
101
        select.from().subquery(this.table.getSubquery());
102

    
103
        List<ExpressionBuilder.Value> valuesToRemoveFeatureType = new ArrayList<>();
104
        List<String> extraColumnNames = new ArrayList<>();
105

    
106
        if (this.query != null && (query.hasAggregateFunctions() || query.hasGroupByColumns())) {
107
            JDBCSQLBuilderBase subsqlbuilder = this.createSQLBuilder();
108
            SelectBuilder subselect = subsqlbuilder.select();
109
            subselect.from().table()
110
                    .database(this.table.getDatabase())
111
                    .schema(this.table.getSchema())
112
                    .name(this.table.getTable());
113
            subselect.from().subquery(this.table.getSubquery());
114

    
115
            // ?sobra?
116
//            process2_ComputedFields(helper, featureType, query, sqlbuilder, subselect, extraColumnNames);
117
            
118
            process3_Where(helper, featureType, query, sqlbuilder, subselect);
119
            process4_Aggregates(this.table, this.featureType, this.query, getAllExtraColumns(this.featureType, this.query), sqlbuilder, subselect, extraColumnNames);
120
            process5_GroupBys(this.table, this.featureType, this.query, getAllExtraColumns(this.featureType, this.query), sqlbuilder, subselect, extraColumnNames);
121
            
122
            if (!StringUtils.isEmpty(baseFilter)) {
123
                subselect.where().and(expbuilder.toValue(baseFilter));
124
            }
125
            
126
            subsqlbuilder.setProperties(
127
                    ExpressionBuilder.Variable.class,
128
                    PROP_FEATURE_TYPE, this.featureType,
129
                    PROP_TABLE, table,
130
                    PROP_SYMBOLTABLE, this.query == null ? null : this.query.getSymbolTable(),
131
                    PROP_JDBCHELPER, this.helper,
132
                    PROP_QUERY, this.query
133
            );
134
            for (ExpressionBuilder.Value value : valuesToRemoveFeatureType) {
135
                value.setProperty(PROP_FEATURE_TYPE, null);
136
            }
137
            this.helper.expandCalculedColumns(subsqlbuilder);
138
            this.helper.processSpecialFunctions(subsqlbuilder, featureType, extraColumnNames);
139
            String subsql = StringUtils.trim(subselect.toString());
140
            select.from().table()
141
                    .database(this.table.getDatabase())
142
                    .schema(this.table.getSchema())
143
                    .name(this.table.getTable());
144
            select.from().subquery(subsql);
145
        } else {
146
            process3_Where(helper, featureType, query, sqlbuilder, select);
147
            if (!StringUtils.isEmpty(baseFilter)) {
148
                sqlbuilder.select().where().set(expbuilder.custom(baseFilter));
149
            }
150
        }
151

    
152

    
153
        select.remove_all_columns();
154
        select.column().value(sqlbuilder.count().all());
155
        sqlbuilder.setProperties(
156
                null,
157
                PROP_FEATURE_TYPE, this.featureType,
158
                PROP_TABLE, table,
159
                PROP_SYMBOLTABLE, this.query==null? null:this.query.getSymbolTable(),
160
                PROP_JDBCHELPER, this.helper,
161
                PROP_QUERY, this.query
162
        );
163
        this.helper.expandCalculedColumns(sqlbuilder);
164
        this.helper.processSpecialFunctions(sqlbuilder, featureType, null);
165

    
166
        select.remove_all_columns();
167
        select.column().value(sqlbuilder.count().all());
168
        
169
        String sql = StringUtils.trim(select.toString());
170
        LOGGER.debug(sql);
171
        return sql;
172
    }
173

    
174
    public long count(JDBCConnection conn) throws DataException {
175

    
176
        String sql = this.getSQL();
177
        Statement st = null;
178
        ResultSet rs = null;
179
        try {
180
            st = conn.createStatement();
181
            rs = JDBCUtils.executeQuery(st, sql);
182
            if (!rs.next()) {
183
                return 0;
184
            }
185
            return rs.getLong(1);
186

    
187
        } catch (SQLException ex) {
188
            throw new JDBCSQLException(ex,sql);
189
        } finally {
190
            JDBCUtils.closeQuietly(st);
191
            JDBCUtils.closeQuietly(rs);
192
        }
193
    }
194
       
195
}