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
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;
9
import org.gvsig.expressionevaluator.ExpressionBuilder.Variable;
10
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
import org.gvsig.fmap.dal.feature.FeatureQueryOrder.FeatureQueryOrderMember;
15
import org.gvsig.fmap.dal.feature.FeatureType;
16
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
17
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory.TableReference;
18
import org.gvsig.fmap.dal.store.jdbc2.ResulSetControler.ResultSetEntry;
19
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
20
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
import org.gvsig.fmap.geom.DataTypes;
23
import org.gvsig.tools.evaluator.Evaluator;
24

    
25
public class ResultSetForSetProviderOperation extends AbstractConnectionOperation {
26
    private final TableReference table;
27
    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
            TableReference table,
39
            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
    protected Object perform_operation() throws Exception {
62
        ResultSetEntry rs = createResultSet(
63
                table, baseFilter, baseOrder, storeType, setType, query, 
64
                limit, offset, fetchSize);
65
        return rs;
66
    }
67
    
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
    public ResultSetEntry createResultSet(
74
            TableReference table,
75
            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
        List<FeatureAttributeDescriptor> columns = new ArrayList<>();
85
        
86
        double tolerance = -1 ; //query.getScale();
87
        JDBCSQLBuilderBase sqlbuilder = createSQLBuilder();
88
        ExpressionBuilder expbuilder = sqlbuilder.expression();
89
        
90
        List<String> primaryKeys = new ArrayList<>();
91
        for(FeatureAttributeDescriptor attr : storeType.getPrimaryKey() ) {
92
            primaryKeys.add(attr.getName());
93
        }
94
        List<String> forcedColumns = new ArrayList<>(primaryKeys);
95

    
96
        String[] constantsAttributeNames = null;
97
        if(query !=null && query.hasConstantsAttributeNames() ) {
98
            constantsAttributeNames = query.getConstantsAttributeNames();
99
        }
100
        for(FeatureAttributeDescriptor attr : setType ) {
101
            if( attr.isComputed() ) {
102
                continue;
103
            }
104
            if( ArrayUtils.contains(constantsAttributeNames, attr.getName()) ) {
105
                continue;
106
            }
107
            if( attr.isPrimaryKey() ) {
108
                forcedColumns.remove(attr.getName());
109
            }
110
            if( attr.getType() == DataTypes.GEOMETRY ) {
111
                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
                columns.add(attr);
123
            } else {
124
                sqlbuilder.select().column().name(attr.getName());
125
                columns.add(attr);
126
            }
127
            if( query !=null && query.isGrouped() ) {
128
                sqlbuilder.select().group_by(expbuilder.column(attr.getName()));
129
            }
130
        }
131
        if( query ==null || !query.isGrouped() ) {
132
            for(String attrName : forcedColumns ) {
133
                sqlbuilder.select().column().name(attrName);
134
                columns.add(setType.getAttributeDescriptor(attrName));
135
            }
136
        }
137
        
138
        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
        
144
        Evaluator filter = query==null? null:query.getFilter();
145
        if( filter != null ) {
146
            String sqlfilter = filter.getSQL();
147
            if( ! StringUtils.isEmpty(sqlfilter) ) {
148
                if( this.helper.supportFilter(this.storeType, filter) ) {
149
                    sqlbuilder.select().where().set(expbuilder.toValue(sqlfilter));
150
                }
151
            }
152
        }
153
        if( ! StringUtils.isEmpty(baseFilter) ) {
154
            sqlbuilder.select().where().and(expbuilder.toValue(baseFilter));
155
        }
156
        
157
        FeatureQueryOrder order = query==null? null:query.getOrder();
158
        if( order != null ) {
159
            for( FeatureQueryOrderMember member : order.members() ) {
160
                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
        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
                sqlbuilder.select().order_by().column(sqlbuilder.as_identifier(attrName)).ascending();
189
            }
190
        }        
191
        if( limit > 0 ) {
192
            sqlbuilder.select().limit(limit);
193
        } else {
194
            sqlbuilder.select().limit(query==null? null:query.getLimit());
195
        }
196
        if( offset>0 ) {
197
            sqlbuilder.select().offset(offset);
198
        }
199
        sqlbuilder.setProperties(
200
                null, 
201
                PROP_FEATURE_TYPE, this.storeType,
202
                PROP_TABLE, table
203
        );
204
        String sql = sqlbuilder.toString();
205
        ResultSetEntry resultSetEntry = this.helper.getResulSetControler().create(
206
                sql, fetchSize, columns.toArray(new FeatureAttributeDescriptor[columns.size()])
207
        );
208
        return resultSetEntry;
209
    }
210

    
211
}