package org.mrcsparker.ceeql; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectReader; import com.github.jknack.handlebars.EscapingStrategy; import com.github.jknack.handlebars.Handlebars; import com.github.jknack.handlebars.Template; import com.github.jknack.handlebars.helper.StringHelpers; import org.mrcsparker.ceeql.handlbars.ConditionalHelper; import org.mrcsparker.ceeql.handlbars.EachHelper; import org.mrcsparker.ceeql.handlbars.FilterHelper; import org.mrcsparker.ceeql.handlbars.ParameterHelper; import org.mrcsparker.ceeql.handlbars.StringHelper; import org.mrcsparker.ceeql.jdbi.NamedParameterRewriter.NameList; import org.skife.jdbi.v2.Handle; import org.skife.jdbi.v2.PreparedBatch; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; class CeeqlTemplate { public static String apply(String s, Map<String, String> args) throws IOException { Context ctx = new Context().apply(s, args, false, null); args.putAll(ctx.parameters); return ctx.sql; } //Testing support static String apply(String s, Map<String, String> args, Map<String, String> parameters, NameList names) throws IOException { Context ctx = new Context().apply(s, args, false, null, parameters, names); args.putAll(ctx.parameters); return ctx.sql; } public static Batch apply(String s, Map<String, String> args, Handle dbiHandle) throws IOException { Context ctx = new Context().apply(s, args, true, dbiHandle); args.putAll(ctx.parameters); return new Batch(ctx.eh); } static class Batch { EachHelper eh; Batch(EachHelper eh) {this.eh = eh;} void define (String key, Object value) { if (eh.batch != null) eh.batch.define(key, value); else if (eh.npbatch != null) eh.npbatch.define(key, value); } int[] execute () { if (eh.batch != null) return eh.batch.execute(); else if (eh.npbatch != null) return eh.npbatch.execute(); else return null; } } static class Context { Map<String, String> parameters; Template template; EachHelper eh; String sql; Context apply(String s, Map<String, String> args, boolean isBatch, Handle dbiHandle) throws IOException { return apply(s, args, isBatch, dbiHandle, new HashMap<String, String>(), new NameList()); } Context apply(String s, Map<String, String> args, boolean isBatch, Handle dbiHandle, Map<String, String> parameters, NameList names) throws IOException { ObjectReader mapper = new ObjectMapper().readerFor(Object.class); HashMap<String, Object> parsedArgs = new HashMap<>(); for (Map.Entry<String, String> a : args.entrySet()) { try { parsedArgs.put(a.getKey(), mapper.readValue(a.getValue())); } catch (Exception e) { parsedArgs.put(a.getKey(), a.getValue()); } } Handlebars handlebars = new Handlebars().with(EscapingStrategy.NOOP); this.parameters = parameters; StringHelper.register(handlebars); StringHelpers.register(handlebars); FilterHelper.register(handlebars); ConditionalHelper.register(handlebars); new ParameterHelper(parameters, names).registerHelper(handlebars); eh = new EachHelper(parameters, names, isBatch, dbiHandle).registerHelper(handlebars); template = handlebars.compileInline(s); sql = template.apply(parsedArgs); return this; } } }