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

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