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

History | View | Annotate | Download (7 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.fmap.dal.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.ResulSetControler.ResultSetEntry;
17
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
18
import org.gvsig.fmap.geom.DataTypes;
19
import org.gvsig.tools.evaluator.Evaluator;
20

    
21
public class ResultSetForSetProviderOperation extends AbstractConnectionOperation {
22
    private final String schema;
23
    private final String table;
24
    private final String subquery;
25
    private final String baseFilter;
26
    private final String baseOrder;
27
    private final FeatureType storeType;
28
    private final FeatureType setType;
29
    private final FeatureQuery query;
30
    private final long limit;
31
    private final long offset;
32
    private final int fetchSize;
33
    private final String database;
34

    
35
    public ResultSetForSetProviderOperation(
36
            JDBCHelper helper,
37
            String database,
38
            String schema,
39
            String table,
40
            String subquery,
41
            String baseFilter,
42
            String baseOrder,
43
            FeatureQuery query,
44
            FeatureType storeType,
45
            FeatureType setType,
46
            long limit,
47
            long offset,
48
            int fetchSize
49
        ) {
50
        super(helper);
51
        this.database = database;
52
        this.schema = schema;
53
        this.table = table;
54
        this.subquery = subquery;
55
        this.baseFilter = baseFilter;
56
        this.baseOrder = baseOrder;
57
        this.storeType = storeType;
58
        this.setType = setType;
59
        this.query = query;
60
        this.limit = limit;
61
        this.offset = offset;
62
        this.fetchSize = fetchSize; 
63
    }
64

    
65
    @Override
66
    public final Object perform(Connection conn) throws DataException {
67
        ResultSetEntry rs = createResultSet(
68
                database, schema, table, subquery, 
69
                baseFilter, baseOrder, storeType, setType, query, 
70
                limit, offset, fetchSize);
71
        return rs;
72
    }
73

    
74
    public ResultSetEntry createResultSet(
75
            String database,
76
            String schema,
77
            String table,
78
            String subquery,
79
            String baseFilter,
80
            String baseOrder,
81
            FeatureType storeType,
82
            FeatureType setType,
83
            FeatureQuery query,
84
            long limit,
85
            long offset,
86
            int fetchSize
87
        ) throws DataException {
88
        List<FeatureAttributeDescriptor> columns = new ArrayList<>();
89
        
90
        double tolerance = -1 ; //query.getScale();
91
        JDBCSQLBuilderBase sqlbuilder = createSQLBuilder();
92
        
93
        List<String> primaryKeys = new ArrayList<>();
94
        for(FeatureAttributeDescriptor attr : storeType.getPrimaryKey() ) {
95
            primaryKeys.add(attr.getName());
96
        }
97
        for(String attrName : primaryKeys ) {
98
            // Ordenamos siempre por las claves primarias para garantizar 
99
            // un orden predecible. Ademas se precisa indicar un orden para
100
            // usar OFFSET.
101
            sqlbuilder.select().order_by().column(sqlbuilder.identifier(attrName)).ascending();
102
        }
103
        String[] constantsAttributeNames = null;
104
        if(query !=null && query.hasConstantsAttributeNames() ) {
105
            constantsAttributeNames = query.getConstantsAttributeNames();
106
        }
107
        for(FeatureAttributeDescriptor attr : setType ) {
108
            if( ArrayUtils.contains(constantsAttributeNames, attr.getName()) ) {
109
                continue;
110
            }
111
            if( attr.isPrimaryKey() ) {
112
                primaryKeys.remove(attr.getName());
113
            }
114
            if( attr.getType() == DataTypes.GEOMETRY ) {
115
                if( tolerance<=0 || !sqlbuilder.getConfig().has_functionality(Config.ST_Simplify)) {
116
                    sqlbuilder.select().column().name(attr.getName()).as_geometry();
117
                } else {
118
                    sqlbuilder.select().column().value(
119
                        sqlbuilder.ST_Simplify( 
120
                            sqlbuilder.column(attr.getName()),
121
                            sqlbuilder.constant(tolerance)
122
                        )
123
                    ).as_geometry();
124
                }
125
                columns.add(attr);
126
            } else {
127
                sqlbuilder.select().column().name(attr.getName());
128
                columns.add(attr);
129
            }
130
        }
131
        for(String attrName : primaryKeys ) {
132
            sqlbuilder.select().column().name(attrName);
133
            columns.add(setType.getAttributeDescriptor(attrName));
134
        }
135
        
136
        if( StringUtils.isEmpty(subquery)  ) {
137
            sqlbuilder.select().from().table().database(database).schema(schema).name(table);
138
        } else {
139
            sqlbuilder.select().from().subquery(subquery);
140
        }
141
        
142
        Evaluator filter = query.getFilter();
143
        if( filter != null ) {
144
            String sqlfilter = filter.getSQL();
145
            if( ! StringUtils.isEmpty(sqlfilter) ) {
146
                sqlbuilder.select().where().set( sqlbuilder.custom(sqlfilter) );
147
            }
148
        }
149
        if( ! StringUtils.isEmpty(baseFilter) ) {
150
            sqlbuilder.select().where().and(sqlbuilder.custom(baseFilter));
151
        }
152
        
153
        FeatureQueryOrder order = query.getOrder();
154
        if( order != null ) {
155
            for( FeatureQueryOrderMember member : order.members() ) {
156
                if( member.hasEvaluator() ) {
157
                    String sqlorder = member.getEvaluator().getSQL();
158
                    if( ! StringUtils.isEmpty(sqlorder) ) {
159
                        sqlbuilder.select().order_by()
160
                                .custom(sqlorder);
161
                    }
162
                } else {
163
                    
164
                    sqlbuilder.select().order_by()
165
                            .column(member.getAttributeName())
166
                            .ascending(member.getAscending());
167
                }
168
            }
169
        }
170
        if( !StringUtils.isEmpty(baseOrder) ) {
171
            sqlbuilder.select().order_by().custom(baseOrder);
172
        }
173
        
174
        if( limit > 0 ) {
175
            sqlbuilder.select().limit(limit);
176
        } else {
177
            sqlbuilder.select().limit(query.getLimit());
178
        }
179
        if( offset>0 ) {
180
            sqlbuilder.select().offset(offset);
181
        }
182
        
183
        String sql = sqlbuilder.toString();
184
        ResultSetEntry resultSetEntry = this.helper.getResulSetControler().create(
185
                sql, fetchSize, columns.toArray(new FeatureAttributeDescriptor[columns.size()])
186
        );
187
        return resultSetEntry;
188
    }
189

    
190
}