Home
Custom FunctionsCustom Functions
Custom functions are basically those specified by the developer to extend the JoSQL functionality in some way. Custom functions can override the built-in functions (see below for details of the search order for functions) to provide differing functionality if required.

To create your own function(s) is trivial. Any public method from any object can be used.

For example, to create a to_string function that will operate on the "current object" (see Current Object Scope), it should have a signature thus:
public String to_string (Object o)
This would then be referred to in the SQL via:
SELECT to_string (12345)
FROM   java.lang.Object
or:
SELECT *
FROM   java.lang.Object
WHERE  toString = to_string (toString)
The custom function can throw any exception, if one is thrown this is wrapped in an instance of: org.josql.QueryExecutionException.
Function Argument Matching
JoSQL tries (wherever possible) to get the "best" match of the arguments to a function to the underlying Java method. However, it also tries to provide flexibility to the developer in that it also allows the developer to take control of how the arguments are handled.

For example, if you use define a function method as:
public Object myFunction (Getter acc)
And then call the function:
SELECT myFunction (name)
FROM   java.io.File
then JoSQL will detect that you actually want the Getter object that represents the access to the getName method in the java.io.File class rather than the value. However if you define your function method as:
public Object myFunction (Object o)
Then JoSQL will execute the Getter for you on the current object and pass the result to the function method instead.

Similarly with functions as arguments, if your function is defined as:
public Object myFunction (List     objs,
                          Function f)
And call from the SQL with:
SELECT myFunction (:_allobjs, toDate (name))
FROM   java.io.File
Then JoSQL will pass the Function object to the function method instead so that you can execute yourself. Note that to execute a Function expression you must have access to the Query object as well.

However if you defined your function method as:
public Object myFunction (List   objs,
                          Object o)
And call from the SQL with:
SELECT myFunction (:_allobjs, toDate (name))
FROM   java.io.File
then JoSQL will execute the toDate(name) function first and then call the myFunction with the result.

The basic rule is that if you wish to have "control" over how the Getter or Function is executed, for example if you wish to execute it over a specific set of objects then use a Getter or Function argument, otherwise use java.lang.Object or a more specific class.

It is also possible to have an "expression" (org.josql.expressions.Expression) passed to the function. Again JoSQL will detect this when matching up the arguments and pass the Expression object rather than the result of evaluating the expression. In this case it is important to know that Expressions use the "current object" and thus this needs to be set via: Query.setCurrentObject(Object) prior to evaluating the expression, AND the current object that was in place prior to execution of the function needs to be "put back" before leaving the function otherwise strange behaviour could result. In general, this advanced aspect of JoSQL shouldn't really be performed unless you have a VERY good reason to do so. See the source for: org.josql.functions.CollectionFunctions.count(List,Expression) for an example of how expressions can be evaluated and handled in a function.
How JoSQL searches for Custom Functions
Custom functions are searched for in the order in which their "handler Object" are added to the Query object.

For example:
Query q = new Query ();
q.addFunctionHandler (new MyFunctionHandler1 ());
q.addFunctionHandler (new MyFunctionHandler2 ());
The instance of MyFunctionHandler1 would thus be search first for the custom function and then the instance of: MyFunctionHandler2.

Note: if JoSQL finds the function in MyFunctionHandler1 it will NOT then search MyFunctionHandler2.

Also, JoSQL only searches within the direct public methods of the handler object, superclass/superinterface methods are NOT searched.

All functions are searched for in the custom handlers first before the built-in handlers are checked, in this way you can easily override the operation of any of the built-in functions with ease.
See Also