package com.philemonworks.critter.dao.sql; import com.google.inject.Inject; import com.philemonworks.critter.Utils; import com.philemonworks.critter.dao.RuleDao; import com.philemonworks.critter.dao.sql.support.JdbcTemplate; import com.philemonworks.critter.dao.sql.support.ParamBinder; import com.philemonworks.critter.dao.sql.support.RowMapper; import com.philemonworks.critter.rule.Rule; import com.philemonworks.critter.rule.RuleConverter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.StringReader; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; /** * Insert documentation here. * * @author jcraane */ public class RuleDaoSqlImpl implements RuleDao { private static final Logger LOG = LoggerFactory.getLogger(RuleDaoSqlImpl.class); private static final String INSERT = "INSERT INTO rules(id, rule_xml) values(?, ?);"; private static final String UPDATE = "UPDATE rules set rule_xml = ? where id = ?"; private static final String SELECT_ALL = "SELECT id, rule_xml FROM rules"; private static final String SELECT_ONE = "SELECT id, rule_xml FROM rules where id = ?"; private static final String DELETE_ONE = "DELETE FROM rules WHERE id = ?"; @Inject private JdbcTemplate jdbcTemplate; @Override public List<Rule> getRules() { return jdbcTemplate.queryForList(SELECT_ALL, new RuleMapper(), null); } @Override public void addOrReplaceRule(final Rule rule) { if (notPresent(rule)) { insert(rule); } else { update(rule); } } private boolean insert(final Rule rule) { return jdbcTemplate.execute(INSERT, new ParamBinder() { @Override public void bind(final PreparedStatement pstm) throws SQLException { pstm.setString(1, rule.id); pstm.setClob(2, new StringReader(RuleConverter.toXml(rule))); } }); } private boolean update(final Rule rule) { return jdbcTemplate.execute(UPDATE, new ParamBinder() { @Override public void bind(final PreparedStatement pstm) throws SQLException { pstm.setClob(1, new StringReader(RuleConverter.toXml(rule))); pstm.setString(2, rule.id); } }); } private boolean notPresent(final Rule rule) { return getRule(rule.id) == null; } @Override public Rule getRule(final String id) { return jdbcTemplate.queryForObject(SELECT_ONE, new RuleMapper(), new IdBinder(id)); } @Override public void deleteRule(final String id) { jdbcTemplate.execute(DELETE_ONE, new IdBinder(id)); } private static final class RuleMapper implements RowMapper<Rule> { @Override public Rule map(final ResultSet rs) throws SQLException, IOException { final String xml = Utils.clobToString(rs.getClob("rule_xml")); String errorMessage = RuleConverter.validateXML(xml); Rule rule = RuleConverter.fromXml(xml, false); if (errorMessage.length() > 0) { rule.enabled = false; rule.invalid = true; } return rule; } } private static final class IdBinder implements ParamBinder { private final String id; private IdBinder(final String id) { this.id = id; } @Override public void bind(final PreparedStatement pstm) throws SQLException { pstm.setString(1, id); } } }