Nuxeo ECM Projects 5.4.3-SNAPSHOT

org.nuxeo.ecm.core.storage.sql.jdbc
Class NXQLQueryMaker

java.lang.Object
  extended by org.nuxeo.ecm.core.storage.sql.jdbc.NXQLQueryMaker
All Implemented Interfaces:
QueryMaker
Direct Known Subclasses:
TagQueryMaker

public class NXQLQueryMaker
extends Object
implements QueryMaker

Transformer of NXQL queries into underlying SQL queries to the actual database.

The examples below are based on the NXQL statement:

 SELECT * FROM File
 WHERE
   dc:title = 'abc'
   AND uid:uid = '123'
   AND dc:contributors = 'bob'    -- multi-valued
 
If there are no proxies (ecm:isProxy = 0) we get:
 SELECT hierarchy.id
   FROM hierarchy
   LEFT JOIN dublincore ON hierarchy.id = dublincore.id
   LEFT JOIN uid ON hierarchy.id = uid.id
 WHERE
   hierarchy.primarytype IN ('File', 'SubFile')
   AND dublincore.title = 'abc'
   AND uid.uid = '123'
   AND EXISTS (SELECT 1 FROM dc_contributors WHERE hierarchy.id = dc_contributors.id
               AND dc_contributors.item = 'bob')
   AND NX_ACCESS_ALLOWED(hierarchy.id, 'user1|user2', 'perm1|perm2')
 
The data tables (dublincore, uid) are joined using a LEFT JOIN, as the schema may not be present on all documents but this shouldn't prevent the WHERE clause from being evaluated. Complex properties are matched using an EXISTS and a subselect. When proxies are matched (ecm:isProxy = 1) there are two additional FULL JOINs. Security checks, id, name, parents and path use the base hierarchy (_H), but all other data use the joined hierarchy.
 SELECT _H.id
   FROM hierarchy _H
   JOIN proxies ON _H.id = proxies.id                     -- proxy full join
   JOIN hierarchy ON hierarchy.id = proxies.targetid      -- proxy full join
   LEFT JOIN dublincore ON hierarchy.id = dublincore.id
   LEFT JOIN uid ON hierarchy.id = uid.id
 WHERE
   hierarchy.primarytype IN ('File', 'SubFile')
   AND dublincore.title = 'abc'
   AND uid.uid = '123'
   AND EXISTS (SELECT 1 FROM dc_contributors WHERE hierarchy.id = dc_contributors.id
               AND dc_contributors.item = 'bob')
   AND NX_ACCESS_ALLOWED(_H.id, 'user1|user2', 'perm1|perm2') -- uses _H
 
When both normal documents and proxies are matched, we UNION ALL the two queries. If an ORDER BY is requested, then columns from the inner SELECTs have to be aliased so that an outer ORDER BY can user their names.

Author:
Florent Guillaume

Nested Class Summary
static class NXQLQueryMaker.DocKind
           
 
Nested classes/interfaces inherited from interface org.nuxeo.ecm.core.storage.sql.jdbc.QueryMaker
QueryMaker.Query, QueryMaker.QueryCannotMatchException, QueryMaker.QueryMakerException
 
Field Summary
static String TYPE_DOCUMENT
           
static String TYPE_RELATION
           
 
Constructor Summary
NXQLQueryMaker()
           
 
Method Summary
 boolean accepts(String queryType)
          Checks if this query maker accepts a given query.
 QueryMaker.Query buildQuery(SQLInfo sqlInfo, Model model, Session.PathResolver pathResolver, String query, QueryFilter queryFilter, Object... params)
          Builds the query.
static String canonicalXPath(String xpath)
          Canonicalizes a Nuxeo-xpath.
 String getName()
          Gets the name for this query maker.
static String simpleXPath(String xpath)
          Turns the xpath into one where all indices have been replaced by *.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

TYPE_DOCUMENT

public static final String TYPE_DOCUMENT
See Also:
Constant Field Values

TYPE_RELATION

public static final String TYPE_RELATION
See Also:
Constant Field Values
Constructor Detail

NXQLQueryMaker

public NXQLQueryMaker()
Method Detail

getName

public String getName()
Description copied from interface: QueryMaker
Gets the name for this query maker.

Specified by:
getName in interface QueryMaker

accepts

public boolean accepts(String queryType)
Description copied from interface: QueryMaker
Checks if this query maker accepts a given query.

Called first.

Specified by:
accepts in interface QueryMaker
Parameters:
queryType - the query
Returns:
true if the query is accepted

buildQuery

public QueryMaker.Query buildQuery(SQLInfo sqlInfo,
                                   Model model,
                                   Session.PathResolver pathResolver,
                                   String query,
                                   QueryFilter queryFilter,
                                   Object... params)
                            throws StorageException
Description copied from interface: QueryMaker
Builds the query.

Specified by:
buildQuery in interface QueryMaker
Parameters:
sqlInfo - the sql info
model - the model
pathResolver - the path resolver
query - the query
queryFilter - the query filter
params - additional parameters, maker-specific
Throws:
StorageException

canonicalXPath

public static String canonicalXPath(String xpath)
Canonicalizes a Nuxeo-xpath.

Replaces a/foo[123]/b with a/123/b

A star or a star followed by digits can be used instead of just the digits as well.

Parameters:
xpath - the xpath
Returns:
the canonicalized xpath.

simpleXPath

public static String simpleXPath(String xpath)
Turns the xpath into one where all indices have been replaced by *.

Parameters:
xpath - the xpath
Returns:
the simple xpath

Nuxeo ECM Projects 5.4.3-SNAPSHOT

Copyright © 2011 Nuxeo SAS. All Rights Reserved.