private String toString(SeQueryInfo qInfo) { StringBuffer sb = new StringBuffer("SeQueryInfo[\n\tcolumns="); try { SeSqlConstruct sql = qInfo.getConstruct(); String[] tables = sql.getTables(); String[] cols = qInfo.getColumns(); String by = null; try { by = qInfo.getByClause(); } catch (NullPointerException npe) { // no-op } String where = sql.getWhere(); for (int i = 0; cols != null && i < cols.length; i++) { sb.append(cols[i]); if (i < cols.length - 1) sb.append(", "); } sb.append("\n\tTables="); for (int i = 0; i < tables.length; i++) { sb.append(tables[i]); if (i < tables.length - 1) sb.append(", "); } sb.append("\n\tWhere="); sb.append(where); sb.append("\n\tOrderBy="); sb.append(by); } catch (SeException e) { sb.append("Exception retrieving query info properties: " + e.getMessage()); } sb.append("]"); return sb.toString(); }
/** * creates an SeQuery with the filters provided to the constructor and returns it. Queries created * with this method can be used to execute and fetch results. They cannot be used for other * operations, such as calculating layer extents, or result count. * * <p>Difference with {@link #createSeQueryForFetch(Session, String[])} is tha this function tells * <code>SeQuery.setSpatialConstraints</code> to NOT return geometry based bitmasks, which are * needed for calculating the query extent and result count, but not for fetching SeRows. * * @param propertyNames names of attributes to build the query for, respecting order * @throws SeException if the ArcSDE Java API throws it while creating the SeQuery or setting it * the spatial constraints. * @throws IOException */ private SeQuery createSeQueryForFetch(String[] propertyNames) throws SeException, IOException { if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest( "constructing new sql query with connection: " + session + ", propnames: " + java.util.Arrays.asList(propertyNames) + " sqlConstruct where clause: '" + this.filters.getSeSqlConstruct().getWhere() + "'"); } final SeQueryInfo qInfo = filters.getQueryInfo(propertyNames); if (sortByClause != null) { qInfo.setByClause(sortByClause); } final SeFilter[] spatialConstraints = this.filters.getSpatialFilters(); if (LOGGER.isLoggable(Level.FINER)) { String msg = "ArcSDE query is: " + toString(qInfo); LOGGER.finer(msg); } final SeQuery seQuery; seQuery = session.prepareQuery(qInfo, spatialConstraints, versioningHandler); return seQuery; }
public static SeQueryInfo parse(ISession session, PlainSelect select) throws SeException, IOException { String[] columns = null; String[] tables = null; String where = null; String orderAndOrGroupByClause = null; if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("building SeQueryInfo to reflect " + select); } // obtain needed SeQueryInfo components columns = getColumns(session, select.getSelectItems()); tables = getTables(select.getFromItems()); Expression whereClause = select.getWhere(); if (whereClause != null) { where = whereClause.toString(); } if (select.getGroupByColumnReferences() != null && select.getGroupByColumnReferences().size() > 0) { String gb = PlainSelect.getFormatedList(select.getGroupByColumnReferences(), " GROUP BY "); orderAndOrGroupByClause = gb; } if (select.getOrderByElements() != null && select.getOrderByElements().size() > 0) { String ob = PlainSelect.orderByToString(select.getOrderByElements()); if (orderAndOrGroupByClause == null) { orderAndOrGroupByClause = ""; } orderAndOrGroupByClause += " " + ob; } // build SeQueryInfo SeQueryInfo qinfo = new SeQueryInfo(); qinfo.setColumns(columns); SeSqlConstruct sqlConstruct = new SeSqlConstruct(); sqlConstruct.setTables(tables); if (where != null) { sqlConstruct.setWhere(where); } qinfo.setConstruct(sqlConstruct); if (orderAndOrGroupByClause != null) { qinfo.setByClause(orderAndOrGroupByClause); } return qinfo; }
/** * Returns an SeQueryInfo that can be used to retrieve a set of SeRows from an ArcSDE layer or a * layer with joins. The SeQueryInfo object lacks the set of column names to fetch. It is the * responsibility of the calling code to call setColumns(String []) on the returned object to * specify which properties to fetch. * * @param unqualifiedPropertyNames non null, possibly empty, list of property names to fetch * @return * @throws IOException */ public SeQueryInfo getQueryInfo(final String[] unqualifiedPropertyNames) throws IOException { assert unqualifiedPropertyNames != null; String[] tables; String byClause = null; final SeSqlConstruct plainSqlConstruct = getSeSqlConstruct(); String where = plainSqlConstruct.getWhere(); try { if (definitionQuery == null) { tables = new String[] {this.sdeTable.getQualifiedName()}; } else { tables = definitionQuery.getConstruct().getTables(); String joinWhere = definitionQuery.getConstruct().getWhere(); if (where == null) { where = joinWhere; } else { where = joinWhere == null ? where : (joinWhere + " AND " + where); } try { byClause = definitionQuery.getByClause(); } catch (NullPointerException e) { // no-op } } final SeQueryInfo qInfo = new SeQueryInfo(); final SeSqlConstruct sqlConstruct = new SeSqlConstruct(); sqlConstruct.setTables(tables); if (where != null && where.length() > 0) { sqlConstruct.setWhere(where); } final int queriedAttCount = unqualifiedPropertyNames.length; if (queriedAttCount > 0) { String[] sdeAttNames = new String[queriedAttCount]; FilterToSQLSDE sqlEncoder = getSqlEncoder(); for (int i = 0; i < queriedAttCount; i++) { String attName = unqualifiedPropertyNames[i]; String coldef = sqlEncoder.getColumnDefinition(attName); sdeAttNames[i] = coldef; } qInfo.setColumns(sdeAttNames); } qInfo.setConstruct(sqlConstruct); if (byClause != null) { qInfo.setByClause(byClause); } return qInfo; } catch (SeException e) { throw new ArcSdeException(e); } }
/** * Creates a query to be executed over an inprocess view (a view defined by a SQL SELECT statement * at the datastore configuration) * * @return the newly created ArcSDEQuery. * @throws IOException see <i>throws DataSourceException</i> bellow. * @see ArcSDEDataStore#registerView(String, PlainSelect) */ public static ArcSDEQuery createInprocessViewQuery( final ISession session, final SimpleFeatureType fullSchema, final Query query, final SeQueryInfo definitionQuery, final PlainSelect viewSelectStatement) throws IOException { final Filter filter = query.getFilter(); final FIDReader fidReader = FIDReader.NULL_READER; // the first table has to be the main layer final SeSqlConstruct construct; try { construct = definitionQuery.getConstruct(); } catch (SeException e) { throw new ArcSdeException("shouldn't happen: " + e.getMessage(), e); } final String[] tables = construct.getTables(); String layerName = tables[0]; // @REVISIT: HACK HERE!, look how to get rid of alias in // query info, or // better stop using queryinfo as definition query and use // the PlainSelect, // then construct the query info dynamically when needed? if (layerName.indexOf(" AS") > 0) { layerName = layerName.substring(0, layerName.indexOf(" AS")); } final SeTable sdeTable = session.getTable(layerName); final SeLayer sdeLayer; if (fullSchema.getGeometryDescriptor() == null) { sdeLayer = null; } else { sdeLayer = session.getLayer(layerName); } // create the set of filters to work over final ArcSDEQuery.FilterSet filters = new ArcSDEQuery.FilterSet( sdeTable, sdeLayer, filter, fullSchema, definitionQuery, viewSelectStatement, fidReader); final Filter unsupportedFilter = filters.getUnsupportedFilter(); final String[] queryProperties = query.getPropertyNames(); final SimpleFeatureType querySchema = getQuerySchema(queryProperties, unsupportedFilter, fullSchema); final ArcSDEQuery sdeQuery; sdeQuery = new ArcSDEQuery( session, querySchema, filters, null, fidReader, ArcSdeVersionHandler.NONVERSIONED_HANDLER); return sdeQuery; }