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 @ 44198

History | View | Annotate | Download (8.24 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 43358 jjdelcerro
            if( ArrayUtils.contains(constantsAttributeNames, attr.getName()) ) {
102
                continue;
103
            }
104 43020 jjdelcerro
            if( attr.isPrimaryKey() ) {
105 43706 jjdelcerro
                forcedColumns.remove(attr.getName());
106 43020 jjdelcerro
            }
107
            if( attr.getType() == DataTypes.GEOMETRY ) {
108 44198 jjdelcerro
                sqlbuilder.select().column().name(attr.getName()).as_geometry();
109
//                if( tolerance<=0 || !sqlbuilder.getConfig().has_functionality(Config.ST_Simplify)) {
110
//                    sqlbuilder.select().column().name(attr.getName()).as_geometry();
111
//                } else {
112
//                    sqlbuilder.select().column().value(
113
//                        sqlbuilder.ST_Simplify(
114
//                            sqlbuilder.column(attr.getName()),
115
//                            sqlbuilder.constant(tolerance)
116
//                        )
117
//                    ).as_geometry();
118
//                }
119 43358 jjdelcerro
                columns.add(attr);
120 43020 jjdelcerro
            } else {
121
                sqlbuilder.select().column().name(attr.getName());
122 43358 jjdelcerro
                columns.add(attr);
123 43020 jjdelcerro
            }
124
        }
125 43706 jjdelcerro
        for(String attrName : forcedColumns ) {
126 43020 jjdelcerro
            sqlbuilder.select().column().name(attrName);
127 43358 jjdelcerro
            columns.add(setType.getAttributeDescriptor(attrName));
128 43020 jjdelcerro
        }
129
130 44058 jjdelcerro
        sqlbuilder.select().from().table()
131
                .database(this.table.getDatabase())
132
                .schema(this.table.getSchema())
133
                .name(this.table.getTable());
134
        sqlbuilder.select().from().subquery(this.table.getSubquery());
135 43020 jjdelcerro
136 44058 jjdelcerro
        Evaluator filter = query==null? null:query.getFilter();
137 43020 jjdelcerro
        if( filter != null ) {
138
            String sqlfilter = filter.getSQL();
139
            if( ! StringUtils.isEmpty(sqlfilter) ) {
140 44198 jjdelcerro
                if( this.helper.supportFilter(this.storeType, filter) ) {
141
                    sqlbuilder.select().where().set(expbuilder.toValue(sqlfilter));
142
                }
143 43020 jjdelcerro
            }
144
        }
145
        if( ! StringUtils.isEmpty(baseFilter) ) {
146 44198 jjdelcerro
            sqlbuilder.select().where().and(expbuilder.toValue(baseFilter));
147 43020 jjdelcerro
        }
148
149 44058 jjdelcerro
        FeatureQueryOrder order = query==null? null:query.getOrder();
150 43020 jjdelcerro
        if( order != null ) {
151 43026 jjdelcerro
            for( FeatureQueryOrderMember member : order.members() ) {
152 43020 jjdelcerro
                if( member.hasEvaluator() ) {
153
                    String sqlorder = member.getEvaluator().getSQL();
154
                    if( ! StringUtils.isEmpty(sqlorder) ) {
155
                        sqlbuilder.select().order_by()
156
                                .custom(sqlorder);
157
                    }
158
                } else {
159
160
                    sqlbuilder.select().order_by()
161
                            .column(member.getAttributeName())
162
                            .ascending(member.getAscending());
163
                }
164
            }
165
        }
166
        if( !StringUtils.isEmpty(baseOrder) ) {
167
            sqlbuilder.select().order_by().custom(baseOrder);
168
        }
169 43706 jjdelcerro
        if( offset>0 || (offset==0 && limit>0) ) {
170
            // No tengo claro que (offset==0 && limit>0) sea lo mas correcto,
171
            // Pero cuando se va a paginar y se pide la primera pagina offset es
172
            // 0 y limit>0, y si no ordenamos ya esa primera pagina los resultados
173
            // que se obtienen no son correctos, ya que la primera pagina se saca
174
            // sin ordenar y el resto ordenadas.
175
            // Probablemente deberiamos tener alguna otra forma de detectar que
176
            // estamos paginanado ya que asi no distinguimo si solo queremos
177
            // obtener los primeros elementos sin importarnos su orden.
178
            for(String attrName : primaryKeys ) {
179
                // Se precisa indicar un orden para usar OFFSET.
180 44198 jjdelcerro
                sqlbuilder.select().order_by().column(sqlbuilder.as_identifier(attrName)).ascending();
181 43706 jjdelcerro
            }
182
        }
183 43020 jjdelcerro
        if( limit > 0 ) {
184
            sqlbuilder.select().limit(limit);
185
        } else {
186 44058 jjdelcerro
            sqlbuilder.select().limit(query==null? null:query.getLimit());
187 43020 jjdelcerro
        }
188
        if( offset>0 ) {
189
            sqlbuilder.select().offset(offset);
190
        }
191 44198 jjdelcerro
        sqlbuilder.setProperties(
192
                Variable.class,
193
                PROP_FEATURE_TYPE, this.storeType,
194
                PROP_TABLE, table
195
        );
196 43020 jjdelcerro
        String sql = sqlbuilder.toString();
197
        ResultSetEntry resultSetEntry = this.helper.getResulSetControler().create(
198 43358 jjdelcerro
                sql, fetchSize, columns.toArray(new FeatureAttributeDescriptor[columns.size()])
199 43020 jjdelcerro
        );
200
        return resultSetEntry;
201
    }
202
203
}