예제 #1
0
  /**
   * Statically analyze a query for various properties.
   *
   * @param query the query to analyze
   * @param params parameters for the query; if necessary parameters are left out they will be
   *     listed as required variables in the analysis
   * @return a query analysis facet
   */
  public QueryAnalysis analyze(String query, Object... params) {
    if (presub) query = presub(query, params);

    long t1 = System.currentTimeMillis(), t2 = 0, t3 = 0;
    DBBroker broker = null;
    try {
      broker = db.acquireBroker();
      prepareContext(broker);
      final org.exist.source.Source source = buildQuerySource(query, params, "analyze");
      final XQuery xquery = broker.getXQueryService();
      final XQueryPool pool = xquery.getXQueryPool();
      CompiledXQuery compiledQuery = pool.borrowCompiledXQuery(broker, source);
      try {
        AnalysisXQueryContext context;
        if (compiledQuery == null) {
          context = new AnalysisXQueryContext(broker, AccessContext.INTERNAL_PREFIX_LOOKUP);
          buildXQueryStaticContext(context, false);
          buildXQueryDynamicContext(context, params, null, false);
          t2 = System.currentTimeMillis();
          compiledQuery = xquery.compile(context, source);
          t3 = System.currentTimeMillis();
        } else {
          context = (AnalysisXQueryContext) compiledQuery.getContext();
          t2 = System.currentTimeMillis();
        }
        return new QueryAnalysis(
            compiledQuery,
            Collections.unmodifiableSet(context.requiredVariables),
            Collections.unmodifiableSet(context.requiredFunctions));
      } finally {
        if (compiledQuery != null) pool.returnCompiledXQuery(source, compiledQuery);
      }
    } catch (XPathException e) {
      LOG.warn(
          "query compilation failed --  "
              + query
              + "  -- "
              + (params == null ? "" : " with params " + Arrays.asList(params))
              + (bindings.isEmpty() ? "" : " and bindings " + bindings));
      throw new DatabaseException("failed to compile query", e);
    } catch (IOException e) {
      throw new DatabaseException("unexpected exception", e);
    } catch (PermissionDeniedException e) {
      throw new DatabaseException("permission denied", e);
    } finally {
      db.releaseBroker(broker);
      STATS.update(query, t1, t2, t3, 0, System.currentTimeMillis());
    }
  }
예제 #2
0
 private CompiledXQuery wrap(
     CompiledXQuery expr, WrapperFactory wrapperFactory, XQueryContext context)
     throws XPathException {
   if (wrapperFactory == null) return expr;
   Function wrapper = wrapperFactory.createWrapper(context);
   wrapper.setArguments(Collections.singletonList((Expression) expr));
   //		wrapper.setSource(expr.getSource());
   return wrapper;
 }
예제 #3
0
 /**
  * Return a string that describes the statistics for the top n entries, sorted by descending
  * order of total time spent dealing with the query. This will always include the totals entry
  * in the first position.
  *
  * @param n the desired number of entries to describe
  * @return a string describing the statistics for the top n entries
  */
 public synchronized String toStringTop(int n) {
   StringBuilder out = new StringBuilder();
   List<Entry> list = entries();
   if (list.isEmpty()) return "<no queries executed>";
   Collections.sort(list, TOTAL_TIME_DESCENDING);
   int maxCountLength = COUNT_FORMAT.format(list.get(0).numQueries).length();
   double totalDuration = list.get(0).queryTime;
   for (Entry entry : list.subList(0, Math.min(n, list.size())))
     out.append(entry.toString(maxCountLength, totalDuration)).append('\n');
   return out.toString();
 }
예제 #4
0
 /**
  * Convert the given object into a value appropriate for being defined as the value of a variable
  * in an XQuery. This will extract a sequence out of all database objects, convert collections and
  * arrays into sequences recursively, convert <code>null</code> into an empty sequence, and pass
  * other objects through untouched. Convertible objects that are defined in the JDK will be
  * automatically converted by eXist.
  *
  * @see org.exist.xquery.XPathUtil#javaObjectToXPath(Object, XQueryContext, boolean)
  * @param o the object to convert to a database value
  * @return the converted value, ready for assignment to an XQuery variable
  */
 @SuppressWarnings("unchecked")
 private Object convertValue(Object o) {
   if (o == null) return Collections.emptyList();
   if (o instanceof Resource) {
     try {
       return ((Resource) o).convertToSequence();
     } catch (UnsupportedOperationException e) {
       return o;
     }
   }
   List<Object> list = null;
   if (o instanceof Collection) list = new ArrayList<Object>((Collection) o);
   else if (o instanceof Object[]) list = new ArrayList<Object>(Arrays.asList((Object[]) o));
   if (list != null) {
     for (ListIterator<Object> it = list.listIterator(); it.hasNext(); ) {
       it.set(convertValue(it.next()));
     }
     return list;
   }
   return DataUtils.toXMLObject(o);
 }