1 16 package scriptella.core; 17 18 import scriptella.configuration.ContentEl; 19 import scriptella.configuration.QueryEl; 20 import scriptella.configuration.ScriptEl; 21 import scriptella.configuration.ScriptingElement; 22 import scriptella.spi.Connection; 23 import scriptella.spi.ParametersCallback; 24 import scriptella.spi.QueryCallback; 25 import scriptella.spi.Resource; 26 27 import java.io.InputStream ; 28 import java.io.Reader ; 29 import java.util.HashMap ; 30 import java.util.List ; 31 import java.util.Map ; 32 import java.util.logging.Level ; 33 import java.util.logging.Logger ; 34 35 36 42 public class QueryExecutor extends ContentExecutor<QueryEl> { 43 private ExecutableElement[] nestedElements; 44 private static final Logger LOG = Logger.getLogger(QueryExecutor.class.getName()); 45 private final boolean debug=LOG.isLoggable(Level.FINE); 46 47 private QueryExecutor(QueryEl queryEl) { 48 super(queryEl); 49 initNestedExecutors(); 50 } 51 52 private void initNestedExecutors() { 53 final List <ScriptingElement> childElements = getElement().getChildScriptinglElements(); 54 nestedElements = new ExecutableElement[childElements.size()]; 55 56 for (int i = 0; i < nestedElements.length; i++) { 57 ScriptingElement element = childElements.get(i); 58 if (element instanceof QueryEl) { 59 nestedElements[i]=QueryExecutor.prepare((QueryEl) element); 60 } else if (element instanceof ScriptEl) { 61 nestedElements[i]=ScriptExecutor.prepare((ScriptEl) element); 62 } else { 63 throw new IllegalStateException ("Type " + element.getClass() + 64 " not supported"); 65 } 66 } 67 } 68 69 public void execute(final DynamicContext ctx) { 70 final Connection c = ctx.getConnection(); 71 72 final Resource content = getContent(c.getDialectIdentifier()); 73 if (content == ContentEl.NULL_CONTENT) { 74 return; 76 } 77 final QueryCtxDecorator ctxDecorator = new QueryCtxDecorator(ctx); 78 if (debug) { 79 LOG.fine("Executing query " + getLocation()); 80 } 81 c.executeQuery(content, ctx, 82 new QueryCallback() { 83 public void processRow(final ParametersCallback params) { 84 EtlCancelledException.checkEtlCancelled(); 85 ctxDecorator.rownum++; 86 ctxDecorator.setParams(params); 87 if (debug) { 88 LOG.fine("Processing row #" + ctxDecorator.rownum + " for query " + getLocation()); 89 } 90 91 for (ExecutableElement exec : nestedElements) { 92 exec.execute(ctxDecorator); 93 } 94 } 95 }); 96 if (debug) { 97 if (ctxDecorator.rownum == 0) { 98 LOG.fine("Query " + getLocation() + " returned no results."); 99 } else { 100 LOG.fine("Query " + getLocation() + " processed."); 101 } 102 103 } 104 105 } 106 107 108 public static ExecutableElement prepare(final QueryEl queryEl) { 109 ExecutableElement q = new QueryExecutor(queryEl); 110 q = StatisticInterceptor.prepare(q, queryEl.getLocation()); 111 q = ConnectionInterceptor.prepare(q, queryEl); 112 q = ExceptionInterceptor.prepare(q, queryEl.getLocation()); 113 q = IfInterceptor.prepare(q, queryEl); 114 115 return q; 116 } 117 118 private static final class QueryCtxDecorator extends DynamicContextDecorator { 119 private static final Object NULL = new Object (); private ParametersCallback params; 121 private int rownum; private Map <String , Object > cachedParams; 123 124 125 public QueryCtxDecorator(DynamicContext context) { 126 super(context); 127 } 128 129 void setParams(final ParametersCallback params) { 130 this.params = params; 131 if (cachedParams != null) { 132 cachedParams.clear(); 133 } 134 } 135 136 @Override 137 public final Object getParameter(final String name) { 138 if ("rownum".equals(name)) { return rownum; 140 } 141 Object res = cachedParams==null?null:cachedParams.get(name); 142 if (res == null) { 143 res = params.getParameter(name); 144 if (res == null) { 145 res = NULL; 146 } 147 if (isCacheable(res)) { 148 if (cachedParams==null) { 149 cachedParams=new HashMap <String , Object >(); 150 } 151 cachedParams.put(name, res); 152 } 153 } 154 return res == NULL ? null : res; 155 } 156 157 162 private boolean isCacheable(Object o) { 163 return !(o instanceof InputStream || o instanceof Reader ); 164 } 165 166 } 167 } 168 | Popular Tags |