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); } }
/** * 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; }