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 / ResultSetForSetProviderOperation.java @ 44374

History | View | Annotate | Download (8.53 KB)

1 43020 jjdelcerro
package org.gvsig.fmap.dal.store.jdbc2.spi.operations;
2
3
import java.sql.Connection;
4
import java.util.ArrayList;
5
import java.util.List;
6 43358 jjdelcerro
import org.apache.commons.lang3.ArrayUtils;
7 43020 jjdelcerro
import org.apache.commons.lang3.StringUtils;
8 44198 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionBuilder;
9
import org.gvsig.expressionevaluator.ExpressionBuilder.Variable;
10 43020 jjdelcerro
import org.gvsig.fmap.dal.exception.DataException;
11
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
12
import org.gvsig.fmap.dal.feature.FeatureQuery;
13
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
14 43026 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureQueryOrder.FeatureQueryOrderMember;
15 43020 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureType;
16
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
17 44058 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory.TableReference;
18 43020 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc2.ResulSetControler.ResultSetEntry;
19
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
20 44198 jjdelcerro
import static org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase.PROP_FEATURE_TYPE;
21
import static org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase.PROP_TABLE;
22 43020 jjdelcerro
import org.gvsig.fmap.geom.DataTypes;
23
import org.gvsig.tools.evaluator.Evaluator;
24
25
public class ResultSetForSetProviderOperation extends AbstractConnectionOperation {
26 44058 jjdelcerro
    private final TableReference table;
27 43020 jjdelcerro
    private final String baseFilter;
28
    private final String baseOrder;
29
    private final FeatureType storeType;
30
    private final FeatureType setType;
31
    private final FeatureQuery query;
32
    private final long limit;
33
    private final long offset;
34
    private final int fetchSize;
35
36
    public ResultSetForSetProviderOperation(
37
            JDBCHelper helper,
38 44058 jjdelcerro
            TableReference table,
39 43020 jjdelcerro
            String baseFilter,
40
            String baseOrder,
41
            FeatureQuery query,
42
            FeatureType storeType,
43
            FeatureType setType,
44
            long limit,
45
            long offset,
46
            int fetchSize
47
        ) {
48
        super(helper);
49
        this.table = table;
50
        this.baseFilter = baseFilter;
51
        this.baseOrder = baseOrder;
52
        this.storeType = storeType;
53
        this.setType = setType;
54
        this.query = query;
55
        this.limit = limit;
56
        this.offset = offset;
57
        this.fetchSize = fetchSize;
58
    }
59
60
    @Override
61 43377 jjdelcerro
    protected Object perform_operation() throws Exception {
62 43020 jjdelcerro
        ResultSetEntry rs = createResultSet(
63 44058 jjdelcerro
                table, baseFilter, baseOrder, storeType, setType, query,
64 43020 jjdelcerro
                limit, offset, fetchSize);
65
        return rs;
66
    }
67 43377 jjdelcerro
68
    @Override
69
    public Object perform(Connection conn) throws DataException {
70
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
71
    }
72
73 43020 jjdelcerro
    public ResultSetEntry createResultSet(
74 44058 jjdelcerro
            TableReference table,
75 43020 jjdelcerro
            String baseFilter,
76
            String baseOrder,
77
            FeatureType storeType,
78
            FeatureType setType,
79
            FeatureQuery query,
80
            long limit,
81
            long offset,
82
            int fetchSize
83
        ) throws DataException {
84 43358 jjdelcerro
        List<FeatureAttributeDescriptor> columns = new ArrayList<>();
85 43020 jjdelcerro
86 43355 jjdelcerro
        double tolerance = -1 ; //query.getScale();
87 43020 jjdelcerro
        JDBCSQLBuilderBase sqlbuilder = createSQLBuilder();
88 44198 jjdelcerro
        ExpressionBuilder expbuilder = sqlbuilder.expression();
89 43020 jjdelcerro
90
        List<String> primaryKeys = new ArrayList<>();
91
        for(FeatureAttributeDescriptor attr : storeType.getPrimaryKey() ) {
92
            primaryKeys.add(attr.getName());
93
        }
94 43706 jjdelcerro
        List<String> forcedColumns = new ArrayList<>(primaryKeys);
95
96 43358 jjdelcerro
        String[] constantsAttributeNames = null;
97
        if(query !=null && query.hasConstantsAttributeNames() ) {
98
            constantsAttributeNames = query.getConstantsAttributeNames();
99
        }
100 43020 jjdelcerro
        for(FeatureAttributeDescriptor attr : setType ) {
101 44324 jjdelcerro
            if( attr.isComputed() ) {
102
                continue;
103
            }
104 43358 jjdelcerro
            if( ArrayUtils.contains(constantsAttributeNames, attr.getName()) ) {
105
                continue;
106
            }
107 43020 jjdelcerro
            if( attr.isPrimaryKey() ) {
108 43706 jjdelcerro
                forcedColumns.remove(attr.getName());
109 43020 jjdelcerro
            }
110
            if( attr.getType() == DataTypes.GEOMETRY ) {
111 44198 jjdelcerro
                sqlbuilder.select().column().name(attr.getName()).as_geometry();
112
//                if( tolerance<=0 || !sqlbuilder.getConfig().has_functionality(Config.ST_Simplify)) {
113
//                    sqlbuilder.select().column().name(attr.getName()).as_geometry();
114
//                } else {
115
//                    sqlbuilder.select().column().value(
116
//                        sqlbuilder.ST_Simplify(
117
//                            sqlbuilder.column(attr.getName()),
118
//                            sqlbuilder.constant(tolerance)
119
//                        )
120
//                    ).as_geometry();
121
//                }
122 43358 jjdelcerro
                columns.add(attr);
123 43020 jjdelcerro
            } else {
124
                sqlbuilder.select().column().name(attr.getName());
125 43358 jjdelcerro
                columns.add(attr);
126 43020 jjdelcerro
            }
127 44374 jjdelcerro
            if( query !=null && query.isGrouped() ) {
128
                sqlbuilder.select().group_by(expbuilder.column(attr.getName()));
129
            }
130 43020 jjdelcerro
        }
131 44374 jjdelcerro
        if( query ==null || !query.isGrouped() ) {
132
            for(String attrName : forcedColumns ) {
133
                sqlbuilder.select().column().name(attrName);
134
                columns.add(setType.getAttributeDescriptor(attrName));
135
            }
136 43020 jjdelcerro
        }
137
138 44058 jjdelcerro
        sqlbuilder.select().from().table()
139
                .database(this.table.getDatabase())
140
                .schema(this.table.getSchema())
141
                .name(this.table.getTable());
142
        sqlbuilder.select().from().subquery(this.table.getSubquery());
143 43020 jjdelcerro
144 44058 jjdelcerro
        Evaluator filter = query==null? null:query.getFilter();
145 43020 jjdelcerro
        if( filter != null ) {
146
            String sqlfilter = filter.getSQL();
147
            if( ! StringUtils.isEmpty(sqlfilter) ) {
148 44198 jjdelcerro
                if( this.helper.supportFilter(this.storeType, filter) ) {
149
                    sqlbuilder.select().where().set(expbuilder.toValue(sqlfilter));
150
                }
151 43020 jjdelcerro
            }
152
        }
153
        if( ! StringUtils.isEmpty(baseFilter) ) {
154 44198 jjdelcerro
            sqlbuilder.select().where().and(expbuilder.toValue(baseFilter));
155 43020 jjdelcerro
        }
156
157 44058 jjdelcerro
        FeatureQueryOrder order = query==null? null:query.getOrder();
158 43020 jjdelcerro
        if( order != null ) {
159 43026 jjdelcerro
            for( FeatureQueryOrderMember member : order.members() ) {
160 43020 jjdelcerro
                if( member.hasEvaluator() ) {
161
                    String sqlorder = member.getEvaluator().getSQL();
162
                    if( ! StringUtils.isEmpty(sqlorder) ) {
163
                        sqlbuilder.select().order_by()
164
                                .custom(sqlorder);
165
                    }
166
                } else {
167
168
                    sqlbuilder.select().order_by()
169
                            .column(member.getAttributeName())
170
                            .ascending(member.getAscending());
171
                }
172
            }
173
        }
174
        if( !StringUtils.isEmpty(baseOrder) ) {
175
            sqlbuilder.select().order_by().custom(baseOrder);
176
        }
177 43706 jjdelcerro
        if( offset>0 || (offset==0 && limit>0) ) {
178
            // No tengo claro que (offset==0 && limit>0) sea lo mas correcto,
179
            // Pero cuando se va a paginar y se pide la primera pagina offset es
180
            // 0 y limit>0, y si no ordenamos ya esa primera pagina los resultados
181
            // que se obtienen no son correctos, ya que la primera pagina se saca
182
            // sin ordenar y el resto ordenadas.
183
            // Probablemente deberiamos tener alguna otra forma de detectar que
184
            // estamos paginanado ya que asi no distinguimo si solo queremos
185
            // obtener los primeros elementos sin importarnos su orden.
186
            for(String attrName : primaryKeys ) {
187
                // Se precisa indicar un orden para usar OFFSET.
188 44198 jjdelcerro
                sqlbuilder.select().order_by().column(sqlbuilder.as_identifier(attrName)).ascending();
189 43706 jjdelcerro
            }
190
        }
191 43020 jjdelcerro
        if( limit > 0 ) {
192
            sqlbuilder.select().limit(limit);
193
        } else {
194 44058 jjdelcerro
            sqlbuilder.select().limit(query==null? null:query.getLimit());
195 43020 jjdelcerro
        }
196
        if( offset>0 ) {
197
            sqlbuilder.select().offset(offset);
198
        }
199 44198 jjdelcerro
        sqlbuilder.setProperties(
200 44369 jjdelcerro
                null,
201 44198 jjdelcerro
                PROP_FEATURE_TYPE, this.storeType,
202
                PROP_TABLE, table
203
        );
204 43020 jjdelcerro
        String sql = sqlbuilder.toString();
205
        ResultSetEntry resultSetEntry = this.helper.getResulSetControler().create(
206 43358 jjdelcerro
                sql, fetchSize, columns.toArray(new FeatureAttributeDescriptor[columns.size()])
207 43020 jjdelcerro
        );
208
        return resultSetEntry;
209
    }
210
211
}