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(); }
/** * 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); } }
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 the envelope for all features within the layer that pass any SQL construct, state, or * spatial constraints for the stream. */ public Envelope calculateQueryExtent() throws IOException { LOGGER.fine("Building a new SeQuery to consult it's resulting envelope"); final SeExtent extent; try { extent = session.issue( new Command<SeExtent>() { @Override public SeExtent execute(ISession session, SeConnection connection) throws SeException, IOException { final String[] spatialCol = {schema.getGeometryDescriptor().getLocalName()}; // fullConstruct may hold information about multiple tables in case of an // in-process view final SeSqlConstruct fullConstruct = filters.getQueryInfo(spatialCol).getConstruct(); String whereClause = fullConstruct.getWhere(); if (whereClause == null) { /* * we really need a where clause or will get a famous -51 DATABASE LEVEL * ERROR with no other explanation on some oracle databases */ whereClause = "1 = 1"; } final SeFilter[] spatialConstraints = filters.getSpatialFilters(); SeExtent extent; final SeQuery extentQuery = new SeQuery(connection); try { versioningHandler.setUpStream(session, extentQuery); if (spatialConstraints.length > 0) { extentQuery.setSpatialConstraints( SeQuery.SE_OPTIMIZE, false, spatialConstraints); } SeSqlConstruct sqlCons = new SeSqlConstruct(); sqlCons.setTables(fullConstruct.getTables()); sqlCons.setWhere(whereClause); final SeQueryInfo seQueryInfo = new SeQueryInfo(); seQueryInfo.setColumns(spatialCol); seQueryInfo.setConstruct(sqlCons); extent = extentQuery.calculateLayerExtent(seQueryInfo); } finally { extentQuery.close(); } return extent; } }); } catch (IOException ex) { SeSqlConstruct sqlCons = this.filters.getSeSqlConstruct(); String sql = (sqlCons == null) ? null : sqlCons.getWhere(); String tables = (sqlCons == null) ? null : Arrays.asList(sqlCons.getTables()).toString(); if (ex.getCause() instanceof SeException) { SeException sdeEx = (SeException) ex.getCause(); if (sdeEx.getSeError().getSdeError() == -288) { // gah, the dreaded 'LOGFILE SYSTEM TABLES DO NOT EXIST' // error. // this error is worthless. Make it quiet, at least. LOGGER.severe( "ArcSDE is complaining that your 'LOGFILE SYSTEM " + "TABLES DO NOT EXIST'. This is an ignorable error."); } } LOGGER.log( Level.SEVERE, "***********************\ntables: " + tables + "\nfilter: " + this.filters.getGeometryFilter() + "\nSQL: " + sql, ex); throw ex; } Envelope envelope = new Envelope(extent.getMinX(), extent.getMaxX(), extent.getMinY(), extent.getMaxY()); if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("got extent: " + extent + ", built envelope: " + envelope); } return envelope; }
/** * 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; }