DataNucleus is developed as a plugin-driven framework and one of the components that is pluggable is the support for JDOQL/JPQL methods in the RDBMS query mechanism. DataNucleus provides support for the majority of SQL methods that you are ever likely to need but is structured so that you could add on support for your own easily enough
The following sections describe how to create your own SQL Method plugin for DataNucleus.
Any SQL Method plugin will need to implement org.datanucleus.store.rdbms.sql.method.SQLMethod . So you need to implement the following interface
import org.datanucleus.store.rdbms.sql.method; public interface SQLMethod { /** * Return the expression for this SQL function. * @param expr The expression that it is invoked on * @param args Arguments passed in * @return The SQL expression using the SQL function */ public SQLExpression getExpression(SQLExpression expr, List args); }
So there is only one method to provide in your implementation. The arguments to this are
So if we wanted to support {String}.length() as an example, so we define our class as
package mydomain; import java.util.List; import java.util.ArrayList; import org.datanucleus.exceptions.NucleusException; import org.datanucleus.store.rdbms.sql.expression.NumericExpression; import org.datanucleus.store.rdbms.sql.expression.SQLExpression; import org.datanucleus.store.rdbms.sql.expression.StringExpression; public class MyStringLengthMethod extends AbstractSQLMethod { public SQLExpression getExpression(SQLExpression expr, List args) { if (expr instanceof StringExpression) { ArrayList funcArgs = new ArrayList(); funcArgs.add(expr); return new NumericExpression("CHAR_LENGTH", funcArgs); } else { throw new NucleusException(Localiser.msg("060001", "length", expr)); } } }
So in this implementation when the user includes {string}.length() this is translated into the SQL _CHARLENGTH({string}) which will certainly work on some RDBMS. Obviously you could use this extension mechanism to support a different underlying SQL function.
So we now have our custom SQL method and we just need to make this into a DataNucleus plugin. To do this you simply add a file plugin.xml to your JAR at the root. The file plugin.xml should look like this
<?xml version="1.0"?> <plugin id="mydomain" name="DataNucleus plug-ins" provider-name="My Company"> <extension point="org.datanucleus.store.rdbms.sql_method"> <sql-method class="java.lang.String" method="length" datastore="h2" evaluator="mydomain.MyStringLengthMethod"/> </extension> </plugin>
If implementing support for a method that is static (e.g JDOHelper.getObjectId()) omit the class argument from the plugin.xml entry, and put the method as JDOHelper.getObjectId Note that you also require a MANIFEST.MF file as per the Extensions Guide.
So we defined calls to a method length for the type java.lang.String for the datastore h2 to use our evaluator. Simple! Whenever this method is encountered in a query from then on for the H2 database it will use our method evaluator.