All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sqlproc.engine.SqlEngine Maven / Gradle / Ivy

There is a newer version: 3.6.1
Show newest version
package org.sqlproc.engine;

import java.security.InvalidParameterException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sqlproc.engine.config.SqlEngineConfiguration;
import org.sqlproc.engine.impl.SqlEmptyMonitor;
import org.sqlproc.engine.impl.SqlMappingRule;
import org.sqlproc.engine.impl.SqlMetaStatement;
import org.sqlproc.engine.impl.SqlMetaStatement.Type;
import org.sqlproc.engine.impl.SqlProcessResult;
import org.sqlproc.engine.impl.SqlUtils;
import org.sqlproc.engine.plugin.SimpleSqlPluginFactory;
import org.sqlproc.engine.plugin.SqlPluginFactory;
import org.sqlproc.engine.type.SqlTypeFactory;
import org.sqlproc.engine.validation.SqlValidator;

/**
 * Common ancestor for {@link SqlQueryEngine}, {@link SqlCrudEngine} and {@link SqlProcedureEngine}.
 * 
 * 

* For more info please see the Tutorials. * * @author Vladimir Hudec */ public abstract class SqlEngine { /** * The internal slf4j logger. */ protected final Logger logger = LoggerFactory.getLogger(getClass()); /** * Name of the META SQL query or statement, which uniquely identifies this instance. */ protected String name; /** * The pre-compiled META SQL query or statement. The META SQL is an ANSI SQL extension using the ANTLR defined * grammar. */ protected SqlMetaStatement statement; /** * The pre-compiled mapping rule, which is an SQL execution result to Java output classes mapping prescription. */ protected SqlMappingRule mapping; /** * Configuration of the SQL Processor using map of features. Optional features can alter the SQL Processor runtime * behavior. */ protected Map features = new HashMap(); /** * Monitor for the runtime statistics gathering. */ protected SqlMonitor monitor; /** * The injected validator. It validates dynamic input values. */ protected SqlValidator validator; /** * The factory for the META types construction. The META type defines the mapping between a Java class type and a * JDBC datatype. For the default META type factory, please see {@link org.sqlproc.engine.jdbc.type.JdbcTypeFactory} * . */ protected SqlTypeFactory typeFactory; /** * The factory for the SQL Processor plugins. This is the basic facility to alter the SQL Processor processing. */ protected SqlPluginFactory pluginFactory; /** * The processing cache used for {@link SqlProcessResult} instances. */ protected ConcurrentHashMap processingCache = new ConcurrentHashMap(); /** * The processing cache statistics. */ protected ConcurrentHashMap processingCacheStatistics = new ConcurrentHashMap(); /** * The overall configuration, which can be persisted. */ private SqlEngineConfiguration configuration; /** * Creates a new instance of the SqlEngine from one META SQL statement and one SQL Mapping rule instance. Both * parameters are already pre-compiled instances using the ANTLR parsers. This is the recommended usage for the * runtime performance optimization. This constructor is devoted to be used from the {@link SqlProcessorLoader}, * which is able to read all statements definitions from an external meta statements file and create the named * SqlEngine instances. Also an external SQL Monitor for the runtime statistics gathering can be engaged. * * @param name * the name of this SQL Engine instance * @param statement * the pre-compiled META SQL statement * @param mapping * the pre-compiled SQL mapping rule * @param monitor * the SQL Monitor for the runtime statistics gathering * @param features * the optional SQL Processor features * @param typeFactory * the factory for the META types construction * @param pluginFactory * the factory for the SQL Processor plugins * @param configuration * the overall configuration, which can be persisted */ public SqlEngine(String name, SqlMetaStatement statement, SqlMappingRule mapping, SqlMonitor monitor, Map features, SqlTypeFactory typeFactory, SqlPluginFactory pluginFactory, SqlEngineConfiguration configuration) { this.name = name; this.statement = statement; this.mapping = mapping; if (features != null) { for (Entry feature : features.entrySet()) setFeature(feature.getKey(), feature.getValue()); } this.monitor = (monitor != null) ? monitor : new SqlEmptyMonitor(); this.typeFactory = typeFactory; this.pluginFactory = (pluginFactory != null) ? pluginFactory : SimpleSqlPluginFactory.getInstance(); this.configuration = configuration; } /** * Injects a validator. It validates dynamic input values. * * @param validator * a generir validator instance */ public void setValidator(SqlValidator validator) { this.validator = validator; } /** * Sets the optional feature in the stament's or global scope. * * @param name * the name of the optional feature * @param value * the value of the optional feature */ public void setFeature(String name, Object value) { features.put(name, value); unsetFeatures(SqlUtils.oppositeFeatures(name)); } /** * Clears the optional features in the stament's or global scope. * * @param names * the names of the optional features */ public void unsetFeatures(Set names) { if (names != null) { for (String name : names) features.remove(name); } } /** * The helper to prevent the NPE * * @param sqlControl * the compound parameters controlling the META SQL execution * @return the object used for the SQL statement static input values */ public static Object getStaticInputValues(SqlControl sqlControl) { if (sqlControl == null) return null; else return sqlControl.getStaticInputValues(); } /** * The helper to prevent the NPE * * @param sqlControl * the compound parameters controlling the META SQL execution * @return the object used for the SQL update statement dynamic input values */ public static Object getDynamicUpdateValues(SqlControl sqlControl) { if (sqlControl == null) return null; else return sqlControl.getDynamicUpdateValues(); } /** * The helper to prevent the NPE * * @param sqlControl * the compound parameters controlling the META SQL execution * @return the max SQL execution time */ public static Integer getMaxTimeout(SqlControl sqlControl) { if (sqlControl == null) return null; else return sqlControl.getMaxTimeout(); } /** * The helper to prevent the NPE * * @param sqlControl * the compound parameters controlling the META SQL execution * @return the first SQL execution output row */ public static Integer getFirstResult(SqlControl sqlControl) { if (sqlControl == null) return null; else return sqlControl.getFirstResult(); } /** * The helper to prevent the NPE * * @param sqlControl * the compound parameters controlling the META SQL execution * @return the max number of SQL execution output rows */ public static Integer getMaxResults(SqlControl sqlControl) { if (sqlControl == null) return null; else return sqlControl.getMaxResults(); } /** * The helper to prevent the NPE * * @param sqlControl * the compound parameters controlling the META SQL execution * @return the ordering directive list */ public static SqlOrder getOrder(SqlControl sqlControl) { if (sqlControl == null || sqlControl.getOrder() == null) return SqlQueryEngine.NO_ORDER; else return sqlControl.getOrder(); } /** * The helper to prevent the NPE * * @param sqlControl * the compound parameters controlling the META SQL execution * @return more result classes used for the return values */ public static Map> getMoreResultClasses(SqlControl sqlControl) { if (sqlControl == null) return null; else return sqlControl.getMoreResultClasses(); } /** * The helper to prevent the NPE * * @param sqlControl * the compound parameters controlling the META SQL execution * @return the optiona features */ public static Map getFeatures(SqlControl sqlControl) { if (sqlControl == null) return null; else return sqlControl.getFeatures(); } /** * The helper to prevent the NPE * * @param sqlControl * the compound parameters controlling the META SQL execution * @return the fetch size of SQL statement */ public static Integer getFetchSize(SqlControl sqlControl) { if (sqlControl == null) return null; else return sqlControl.getFetchSize(); } /** * Check the input parameters. * * @param dynamicInputValues * The object used for the SQL statement dynamic input values. The class of this object is also named as * the input class or the dynamic parameters class. The exact class type isn't important, all the * parameters settled into the SQL prepared statement are picked up using the reflection API. * @throws InvalidParameterException * in the case the incorrect classes used for dynamic input values */ void checkDynamicInputValues(final Object dynamicInputValues) { if (dynamicInputValues == null) return; if (dynamicInputValues instanceof SqlOrder) throw new InvalidParameterException("SqlOrder used as dynamic input values"); if (dynamicInputValues instanceof SqlControl) throw new InvalidParameterException("SqlControl used as dynamic input values"); } /** * Check the input parameters. * * @param staticInputValues * The object used for the SQL statement static input values. The class of this object is also named as * the input class or the static parameters class. The exact class type isn't important, all the * parameters injected into the SQL query command are picked up using the reflection API. Compared to * dynamicInputValues input parameters, parameters in this class should't be produced by an end user to * prevent SQL injection threat! * @throws InvalidParameterException * in the case the incorrect classes used for static input values */ void checkStaticInputValues(final Object staticInputValues) { if (staticInputValues == null) return; if (staticInputValues instanceof SqlOrder) throw new InvalidParameterException("SqlOrder used as static input values"); if (staticInputValues instanceof SqlControl) throw new InvalidParameterException("SqlControl used as static input values"); } /** * Returns the optional features, which can alter the SQL Processor runtime behavior. * * @return the optional features, which can alter the SQL Processor runtime behavior */ public Map getFeatures() { return features; } /** * Returns the factory for the META types construction. The META type defines the mapping between a Java class type * and a JDBC datatype. For the default META type factory, please see * {@link org.sqlproc.engine.jdbc.type.JdbcTypeFactory} * * @return the factory for the META types construction */ public SqlTypeFactory getTypeFactory() { return typeFactory; } /** * Returns the factory for the SQL Processor plugins. This is the basic facility to alter the SQL Processor * processing. * * @return the factory for the SQL Processor plugins */ public SqlPluginFactory getPluginFactory() { return pluginFactory; } /** * Returns the processing cache used for {@link SqlProcessResult} instances. * * @return the processing cache used for {@link SqlProcessResult} instances. */ public ConcurrentHashMap getProcessingCache() { return processingCache; } /** * Sets the processing cache used for {@link SqlProcessResult} instances. * * @param processingCache * the processing cache used for {@link SqlProcessResult} instances. */ public void setProcessingCache(ConcurrentHashMap processingCache) { this.processingCache = processingCache; } /** * Returns the processing cache statistics. * * @return the processing cache statistics */ public ConcurrentHashMap getProcessingCacheStatistics() { return processingCacheStatistics; } /** * Sets the processing cache statistics. * * @param processingCacheStatistics * the processing cache statistics */ public void setProcessingCacheStatistics(ConcurrentHashMap processingCacheStatistics) { this.processingCacheStatistics = processingCacheStatistics; } /** * The main contract for a dynamic ANSI SQL Query generation. * * The ANSI SQL Query creation is based on *

    *
  • META SQL *
  • dynamic input values *
  • static input values *
  • ordering list directive *
  • optional features *
      * * @param sqlStatementType * the SQL command type * @param dynamicInputValues * the SQL statement dynamic parameters (input values) * @param sqlControl * The compound parameters controlling the META SQL execution * @return the crate for ANSI SQL and other attributes, which control the SQL statement itself */ protected SqlProcessResult process(Type sqlStatementType, Object dynamicInputValues, SqlControl sqlControl) { SqlProcessResult processResult = null; String processingId = null; if (configuration != null && configuration.getUseProcessingCache() != null && configuration.getUseProcessingCache()) { boolean doGetProcessingId = false; if (!configuration.getDoProcessingCacheEngines().isEmpty()) { if (configuration.getDoProcessingCacheEngines().contains(name)) doGetProcessingId = true; } else if (!configuration.getDontProcessingCacheEngines().isEmpty()) { if (!configuration.getDontProcessingCacheEngines().contains(name)) doGetProcessingId = true; } else { doGetProcessingId = true; } if (doGetProcessingId) processingId = pluginFactory.getSqlProcessingIdPlugin().getProcessingId(name, dynamicInputValues, sqlControl, configuration.getUseDynamicProcessingCache()); } if (processingId != null) processResult = processingCache.get(processingId); if (processResult != null) { processingCacheStatistics.get(processingId).incrementAndGet(); return new SqlProcessResult(processResult, dynamicInputValues, sqlControl); } processResult = statement.process(sqlStatementType, dynamicInputValues, sqlControl, this); if (processingId == null) return processResult; AtomicLong firstCounter = processingCacheStatistics.putIfAbsent(processingId, new AtomicLong(1L)); if (firstCounter != null) processingCacheStatistics.get(processingId).addAndGet(firstCounter.get()); SqlProcessResult firstProcessResult = processingCache.putIfAbsent(processingId, processResult); return firstProcessResult != null ? firstProcessResult : processResult; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy