|
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 "new" 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
-
The expression on which the method is invoked. So if you have
{string}.myMethod(args)
then the first argument will be a
StringExpression
. If the method is a function then this argument is null
-
The args are the arguments passed in to the method call. They will be
SQLExpression/SQLLiteral.
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
CHAR_LENGTH({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="indexOf" 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
Plugins 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.
|
|