Search in sources :

Example 11 with JpqlFunction

use of com.blazebit.persistence.spi.JpqlFunction in project blaze-persistence by Blazebit.

the class DataNucleus51EntityManagerFactoryIntegrator method getRegisteredFunctions.

@Override
public Map<String, JpqlFunction> getRegisteredFunctions(EntityManagerFactory entityManagerFactory) {
    NucleusContext context = entityManagerFactory.unwrap(NucleusContext.class);
    RDBMSStoreManager storeMgr = (RDBMSStoreManager) entityManagerFactory.unwrap(StoreManager.class);
    String storeName = storeMgr.getDatastoreAdapter().getVendorID();
    SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
    Set<Object> methodKeys = fieldGet("pluginSqlMethodsKeysSupported", exprFactory);
    Map<String, JpqlFunction> functions = new HashMap<>();
    // We need to construct a statement object and how this is done changed between 4 and 5 so we have to do a little reflection hack
    // We need this because the function methods retrieve the expression factory through it
    Class<?>[] parameterTypes = { RDBMSStoreManager.class, Table.class, DatastoreIdentifier.class, String.class };
    SQLStatement stmt;
    try {
        Constructor c = Class.forName("org.datanucleus.store.rdbms.sql.SelectStatement").getConstructor(parameterTypes);
        stmt = (SQLStatement) c.newInstance(storeMgr, null, null, null);
    } catch (Exception e) {
        try {
            Constructor c = Class.forName("org.datanucleus.store.rdbms.sql.SQLStatement").getConstructor(parameterTypes);
            stmt = (SQLStatement) c.newInstance(storeMgr, null, null, null);
        } catch (Exception e2) {
            throw new RuntimeException("Could not access the required methods to dynamically retrieve registered functions. Please report this version of datanucleus(" + VERSION + ") so we can provide support for it!", e2);
        }
    }
    // Well apparently expressions get their class loader resolver by asking the statement they are part of
    // which in turn asks the query generator that is responsible for it
    // So this is the most non-hackish way to get this to work...
    QueryGenerator noopGenerator = (QueryGenerator) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { QueryGenerator.class }, new QueryGeneratorInvocationHandler(context));
    stmt.setQueryGenerator(noopGenerator);
    try {
        Method getMethod = SQLExpressionFactory.class.getDeclaredMethod("getMethod", String.class, String.class, List.class);
        getMethod.setAccessible(true);
        for (Object methodKey : methodKeys) {
            String className = fieldGet("clsName", methodKey);
            String datastoreName = fieldGet("datastoreName", methodKey);
            String name = fieldGet("methodName", methodKey);
            if (className.isEmpty() && name.indexOf('.') == -1 && ("ALL".equals(datastoreName) || storeName.equals(datastoreName))) {
                // Only consider normal functions
                SQLMethod method = (SQLMethod) getMethod.invoke(exprFactory, null, name, Collections.emptyList());
                if (method instanceof DataNucleusJpqlFunctionAdapter) {
                    functions.put(name, ((DataNucleusJpqlFunctionAdapter) method).unwrap());
                } else {
                    functions.put(name, new JpqlFunctionSQLMethod(stmt, method));
                }
            }
        }
        for (String name : BUILTIN_FUNCTIONS) {
            SQLMethod method = (SQLMethod) getMethod.invoke(exprFactory, null, name, Collections.emptyList());
            if (method instanceof DataNucleusJpqlFunctionAdapter) {
                functions.put(name, ((DataNucleusJpqlFunctionAdapter) method).unwrap());
            } else {
                functions.put(name, new JpqlFunctionSQLMethod(stmt, method));
            }
        }
        // The length function is the single exception to all functions that is based on a class
        SQLMethod method = (SQLMethod) getMethod.invoke(exprFactory, "java.lang.String", "length", Collections.emptyList());
        functions.put("length", new JpqlFunctionInstanceSQLMethod(stmt, method));
    } catch (Exception ex) {
        throw new RuntimeException("Could not access the required methods to dynamically retrieve registered functions. Please report this version of datanucleus(" + VERSION + ") so we can provide support for it!", ex);
    }
    return functions;
}
Also used : JpqlFunction(com.blazebit.persistence.spi.JpqlFunction) SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) HashMap(java.util.HashMap) Constructor(java.lang.reflect.Constructor) NucleusContext(org.datanucleus.NucleusContext) SQLMethod(org.datanucleus.store.rdbms.sql.method.SQLMethod) Method(java.lang.reflect.Method) SQLStatement(org.datanucleus.store.rdbms.sql.SQLStatement) IOException(java.io.IOException) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) StoreManager(org.datanucleus.store.StoreManager) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) QueryGenerator(org.datanucleus.store.rdbms.query.QueryGenerator) SQLMethod(org.datanucleus.store.rdbms.sql.method.SQLMethod)

Example 12 with JpqlFunction

use of com.blazebit.persistence.spi.JpqlFunction in project blaze-persistence by Blazebit.

the class CriteriaBuilderConfigurationImpl method findFunction.

private <T extends JpqlFunction> T findFunction(String name, String dbms) {
    JpqlFunctionGroup jpqlFunctionGroup = functions.get(name);
    JpqlFunction jpqlFunction = jpqlFunctionGroup.get(dbms);
    if (jpqlFunction == null) {
        jpqlFunction = jpqlFunctionGroup.get(null);
    }
    return (T) jpqlFunction;
}
Also used : JpqlFunction(com.blazebit.persistence.spi.JpqlFunction) JpqlFunctionGroup(com.blazebit.persistence.spi.JpqlFunctionGroup)

Aggregations

JpqlFunction (com.blazebit.persistence.spi.JpqlFunction)12 HashMap (java.util.HashMap)8 JpqlFunctionGroup (com.blazebit.persistence.spi.JpqlFunctionGroup)5 Map (java.util.Map)5 StoreManager (org.datanucleus.store.StoreManager)4 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)4 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)4 CountStarFunction (com.blazebit.persistence.integration.jpa.function.CountStarFunction)3 EntityManager (javax.persistence.EntityManager)3 SQLMethod (org.datanucleus.store.rdbms.sql.method.SQLMethod)3 IOException (java.io.IOException)2 Constructor (java.lang.reflect.Constructor)2 TreeMap (java.util.TreeMap)2 NucleusContext (org.datanucleus.NucleusContext)2 QueryGenerator (org.datanucleus.store.rdbms.query.QueryGenerator)2 SQLStatement (org.datanucleus.store.rdbms.sql.SQLStatement)2 ExpressionOperator (org.eclipse.persistence.expressions.ExpressionOperator)2 AbstractSession (org.eclipse.persistence.internal.sessions.AbstractSession)2 JpaEntityManagerFactory (org.eclipse.persistence.jpa.JpaEntityManagerFactory)2 DatabasePlatform (org.eclipse.persistence.platform.database.DatabasePlatform)2