com.virtusa.gto.nyql.engine.NyQLInstance.groovy Maven / Gradle / Ivy
package com.virtusa.gto.nyql.engine
import com.virtusa.gto.nyql.configs.ConfigBuilder
import com.virtusa.gto.nyql.configs.ConfigKeys
import com.virtusa.gto.nyql.configs.ConfigParser
import com.virtusa.gto.nyql.configs.Configurations
import com.virtusa.gto.nyql.exceptions.NyException
import com.virtusa.gto.nyql.model.QScript
import com.virtusa.gto.nyql.model.QSession
import groovy.json.JsonOutput
import groovy.transform.CompileStatic
import java.util.function.BiFunction
/**
* @author IWEERARATHNA
*/
@CompileStatic
class NyQLInstance {
private static final Map EMPTY_MAP = [:]
private final Configurations configurations
private NyQLInstance(Configurations theConfigInstance) {
this.configurations = theConfigInstance
}
static NyQLInstance create(InputStream inputStream) {
create(ConfigParser.parseAndResolve(inputStream))
}
static NyQLInstance create(File configFile) {
create(ConfigParser.parseAndResolve(configFile))
}
static NyQLInstance create(Map configData) {
configData.put(ConfigKeys.LOCATION_KEY, new File('.').canonicalPath)
Configurations configInst = ConfigBuilder.instance().setupFrom(configData).build()
create(configInst)
}
static NyQLInstance create(Configurations configInst) {
new NyQLInstance(configInst)
}
Configurations getConfigurations() {
return configurations
}
/**
*
* Parse the given file indicated from given script name and returns the generated query
* with its other information. Your script name would be the relative path from the
* script root directory, always having forward slashes (/).
*
* You should call this only if you are working with a script repository.
*
* @param scriptName name of the script.
* @return generated query instance.
* @throws com.virtusa.gto.nyql.exceptions.NyException any exception thrown while parsing.
*/
@CompileStatic
QScript parse(String scriptName) throws NyException {
parse(scriptName, EMPTY_MAP)
}
/**
*
* Parse the given file indicated from given script name using the given variable set
* and returns the generated query
* with its other information. Your script name would be the relative path from the
* script root directory, always having forward slashes (/).
*
* You should call this only if you are working with a script repository.
*
* @param scriptName name of the script.
* @param data set of variable data required for generation of query.
* @return generated query instance.
* @throws NyException any exception thrown while parsing.
*/
@CompileStatic
QScript parse(String scriptName, Map data) throws NyException {
QSession qSession = QSession.create(configurations, scriptName)
if (data) {
qSession.sessionVariables.putAll(data)
}
configurations.repositoryRegistry.defaultRepository().parse(scriptName, qSession)
}
/**
* Shutdown the nyql engine.
* This should be called only when your application exits.
*/
void shutdown() {
configurations.shutdown()
}
/**
*
* Executes a given file indicated by the script name and returns the final result
* which was output of the last statement in the script ran.
*
*
* This method will automatically parse the script and execute using internally
* configured executor.
*
*
* @param scriptName name of the script to be run.
* @return the result of the script execution.
* @throws NyException any exception thrown while parsing or executing.
*/
@CompileStatic
T execute(String scriptName) throws NyException {
(T) execute(scriptName, EMPTY_MAP)
}
/**
*
* Executes a given file indicated by the script name using given set of variables
* and returns the final result
* which was output of the last statement in the script ran.
*
*
* This method will automatically parse the script and execute using internally
* configured executor.
*
* Note:
* You should pass all parameter values required for the query execution.
*
* @param scriptName name of the script to be run.
* @param data set of variables to be passed to the script run.
* @return the result of the script execution.
* @throws NyException any exception thrown while parsing or executing.
*/
@CompileStatic
T execute(String scriptName, Map data) throws NyException {
QScript script = null
try {
script = parse(scriptName, data)
(T) configurations.executorRegistry.defaultExecutorFactory().create().execute(script)
} finally {
if (script != null) {
script.free()
}
}
}
/**
* Executes the given script and returns the result as a json string.
*
* If you still want to parse the json again, use the other execute method
* execute(String, Map)
.
*
*
* @param scriptName name of the script to run.
* @param data set of variables required for script.
* @return result as json string.
* @throws NyException any exception thrown while executing and parsing.
*/
@CompileStatic
String executeToJSON(String scriptName, Map data) throws NyException {
Object result = execute(scriptName, data)
if (result == null) {
null
} else {
JsonOutput.toJson(result)
}
}
/**
* Executes the given script and returns the result as a json string.
*
* If you still want to parse the json again, use the other execute method
* execute(String, Map)
.
*
*
* @param scriptName name of the script to run.
* @return result as json string.
* @throws NyException any exception thrown while executing and parsing.
*/
@CompileStatic
String executeToJSON(String scriptName) throws NyException {
executeToJSON(scriptName, [:])
}
/**
* Programmatically (using API) do some sequence of operations inside a transaction. This would
* be useful, specially if you don't want to script your transaction logic externally. In case
* of an exception, transaction will be rollback automatically, but will throw the exception.
*
* Always use the provided nyql instance to execute scripts at all.
*
* @param transactionName a unique id for this executing transaction.
* @param body the content of transaction.
* @param parameter data for the transaction content.
* @param autoCommit should do auto commit
* @throws NyException any exception thrown while transaction.
*/
@CompileStatic
T doTransaction(String transactionName, BiFunction, T> body,
Map data, boolean autoCommit) throws NyException {
QSession qSession = QSession.create(configurations, transactionName)
try {
qSession.executor.startTransaction()
T result = body.apply(this, data)
if (autoCommit) {
qSession.executor.commit()
}
result
} catch (Exception ex) {
qSession.executor.rollback(null)
throw new NyException("An exception occurred inside transaction '$transactionName'!", ex)
} finally {
qSession.executor.done()
}
}
}