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
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
import org.apache.commons.lang3.ArrayUtils;
7
import org.apache.commons.lang3.StringUtils;
8
import org.gvsig.expressionevaluator.ExpressionBuilder.Config;
9
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
import org.gvsig.fmap.dal.feature.FeatureQueryOrder.FeatureQueryOrderMember;
14
import org.gvsig.fmap.dal.feature.FeatureType;
15
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
16
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory.TableReference;
17
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
    private final TableReference table;
24
    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
            TableReference table,
36
            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
    protected Object perform_operation() throws Exception {
59
        ResultSetEntry rs = createResultSet(
60
                table, baseFilter, baseOrder, storeType, setType, query, 
61
                limit, offset, fetchSize);
62
        return rs;
63
    }
64
    
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
    public ResultSetEntry createResultSet(
71
            TableReference table,
72
            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
        List<FeatureAttributeDescriptor> columns = new ArrayList<>();
82
        
83
        double tolerance = -1 ; //query.getScale();
84
        JDBCSQLBuilderBase sqlbuilder = createSQLBuilder();
85
        
86
        List<String> primaryKeys = new ArrayList<>();
87
        for(FeatureAttributeDescriptor attr : storeType.getPrimaryKey() ) {
88
            primaryKeys.add(attr.getName());
89
        }
90
        List<String> forcedColumns = new ArrayList<>(primaryKeys);
91

    
92
        String[] constantsAttributeNames = null;
93
        if(query !=null && query.hasConstantsAttributeNames() ) {
94
            constantsAttributeNames = query.getConstantsAttributeNames();
95
        }
96
        for(FeatureAttributeDescriptor attr : setType ) {
97
            if( ArrayUtils.contains(constantsAttributeNames, attr.getName()) ) {
98
                continue;
99
            }
100
            if( attr.isPrimaryKey() ) {
101
                forcedColumns.remove(attr.getName());
102
            }
103
            if( attr.getType() == DataTypes.GEOMETRY ) {
104
                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
                columns.add(attr);
115
            } else {
116
                sqlbuilder.select().column().name(attr.getName());
117
                columns.add(attr);
118
            }
119
        }
120
        for(String attrName : forcedColumns ) {
121
            sqlbuilder.select().column().name(attrName);
122
            columns.add(setType.getAttributeDescriptor(attrName));
123
        }
124
        
125
        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
        
131
        Evaluator filter = query==null? null:query.getFilter();
132
        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
        FeatureQueryOrder order = query==null? null:query.getOrder();
143
        if( order != null ) {
144
            for( FeatureQueryOrderMember member : order.members() ) {
145
                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
        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
        if( limit > 0 ) {
177
            sqlbuilder.select().limit(limit);
178
        } else {
179
            sqlbuilder.select().limit(query==null? null:query.getLimit());
180
        }
181
        if( offset>0 ) {
182
            sqlbuilder.select().offset(offset);
183
        }
184
        
185
        String sql = sqlbuilder.toString();
186
        ResultSetEntry resultSetEntry = this.helper.getResulSetControler().create(
187
                sql, fetchSize, columns.toArray(new FeatureAttributeDescriptor[columns.size()])
188
        );
189
        return resultSetEntry;
190
    }
191

    
192
}