package com.breakersoft.plow.dao.pgsql;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import com.breakersoft.plow.Defaults;
import com.breakersoft.plow.FrameRange;
import com.breakersoft.plow.FrameSet;
import com.breakersoft.plow.Job;
import com.breakersoft.plow.Layer;
import com.breakersoft.plow.LayerE;
import com.breakersoft.plow.dao.AbstractDao;
import com.breakersoft.plow.dao.LayerDao;
import com.breakersoft.plow.dispatcher.DispatchConfig;
import com.breakersoft.plow.thrift.LayerSpecT;
import com.breakersoft.plow.util.JdbcUtils;
import com.breakersoft.plow.util.PlowUtils;
@Repository
public class LayerDaoImpl extends AbstractDao implements LayerDao {
@SuppressWarnings("unused")
private static final Logger logger =
org.slf4j.LoggerFactory.getLogger(LayerDaoImpl.class);
public static final RowMapper<Layer> MAPPER = new RowMapper<Layer>() {
@Override
public Layer mapRow(ResultSet rs, int rowNum)
throws SQLException {
LayerE layer = new LayerE();
layer.setLayerId(UUID.fromString(rs.getString(1)));
layer.setJobId(UUID.fromString(rs.getString(2)));
layer.setName(rs.getString(3));
return layer;
}
};
private static final String GET =
"SELECT " +
"pk_layer,"+
"pk_job, " +
"str_name " +
"FROM " +
"plow.layer ";
@Override
public Layer get(Job job, String name) {
try {
return get(UUID.fromString(name));
} catch (IllegalArgumentException e) {
return jdbc.queryForObject(
GET + "WHERE pk_job=? AND str_name=?",
MAPPER, job.getJobId(), name);
}
}
@Override
public Layer get(Job job, int idx) {
return jdbc.queryForObject(
GET + "WHERE pk_job=? AND int_order=? LIMIT 1",
MAPPER, job.getJobId(), idx);
}
@Override
public Layer get(UUID id) {
return jdbc.queryForObject(
GET + "WHERE pk_layer=?",
MAPPER, id);
}
private static final String INSERT =
"INSERT INTO " +
"plow.layer " +
"(" +
"pk_layer,"+
"pk_job,"+
"str_name,"+
"str_range,"+
"str_command,"+
"str_tags,"+
"int_chunk_size,"+
"int_order,"+
"int_cores_min,"+
"int_cores_max,"+
"int_ram_min,"+
"int_ram_max,"+
"int_retries_max,"+
"bool_threadable,"+
"hstore_env,"+
"str_service " +
") " +
"VALUES (" +
StringUtils.repeat("?",",",16) +
")";
@Override
public Layer create(final Job job, final LayerSpecT layer, final int order) {
PlowUtils.alpahNumCheck(layer.getName(), "The layer name must be alpha numeric.");
final UUID id = UUID.randomUUID();
jdbc.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(final Connection conn) throws SQLException {
final PreparedStatement ret = conn.prepareStatement(INSERT);
ret.setObject(1, id);
ret.setObject(2, job.getJobId());
ret.setString(3, layer.getName());
ret.setString(4, layer.getRange());
ret.setArray(5, conn.createArrayOf("text", layer.getCommand().toArray()));
ret.setArray(6, conn.createArrayOf("text", layer.getTags().toArray()));
ret.setInt(7, layer.getChunk());
ret.setInt(8, order);
ret.setInt(9, layer.getMinCores());
ret.setInt(10, layer.getMaxCores());
ret.setInt(11, layer.getMinRam());
ret.setInt(12, layer.getMaxRam());
ret.setInt(13, layer.getMaxRetries());
ret.setBoolean(14, layer.isThreadable());
ret.setObject(15, layer.getEnv());
ret.setString(16, layer.getServ());
return ret;
}
});
jdbc.update("INSERT INTO plow.layer_count (pk_layer) VALUES (?)", id);
jdbc.update("INSERT INTO plow.layer_dsp (pk_layer) VALUES (?)", id);
jdbc.update("INSERT INTO plow.layer_stat (pk_layer, pk_job) VALUES (?, ?)", id, job.getJobId());
final LayerE result = new LayerE();
result.setLayerId(id);
result.setJobId(job.getJobId());
result.setName(layer.getName());
return result;
}
@Override
public boolean isFinished(Layer layer) {
return jdbc.queryForObject(
"SELECT int_total - (int_succeeded + int_eaten) AS t " +
"FROM layer_count WHERE pk_layer=?", Integer.class, layer.getLayerId()) == 0;
}
private static final RowMapper<FrameRange> RANGE_MAPPER = new RowMapper<FrameRange>() {
@Override
public FrameRange mapRow(ResultSet rs, int rowNum)
throws SQLException {
return new FrameRange(new FrameSet(rs.getString("str_range")), rs.getInt("int_chunk_size"));
}
};
@Override
public FrameRange getFrameRange(Layer layer) {
return jdbc.queryForObject(
"SELECT str_range, int_chunk_size FROM plow.layer WHERE pk_layer=?",
RANGE_MAPPER, layer.getLayerId());
}
@Override
public void setMinCores(Layer layer, int cores) {
jdbc.update("UPDATE plow.layer SET int_cores_min=? WHERE pk_layer=?",
Math.max(cores, Defaults.LAYER_MIN_MIN_CORES), layer.getLayerId());
}
@Override
public void setMaxCores(Layer layer, int cores) {
jdbc.update("UPDATE plow.layer SET int_cores_max=? WHERE pk_layer=?",
Math.min(cores, Defaults.LAYER_MAX_MAX_CORES), layer.getLayerId());
}
@Override
public void setMinRam(Layer layer, int memory) {
jdbc.update("UPDATE plow.layer SET int_ram_min=? WHERE pk_layer=?",
Math.max(memory, Defaults.LAYER_MIN_MIN_RAM), layer.getLayerId());
}
@Override
public void setMaxRam(Layer layer, int memory) {
jdbc.update("UPDATE plow.layer SET int_ram_max=? WHERE pk_layer=?",
Math.min(memory, Defaults.LAYER_MAX_MAX_RAM), layer.getLayerId());
}
@Override
public void setThreadable(Layer layer, boolean threadable) {
jdbc.update("UPDATE plow.layer SET bool_threadable=? WHERE pk_layer=?",
threadable, layer.getLayerId());
}
private static final String UPDATE_TAGS =
"UPDATE plow.layer SET str_tags=? WHERE pk_layer=?";
@Override
public void setTags(final Layer layer, final List<String> tags) {
jdbc.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(final Connection conn) throws SQLException {
final PreparedStatement ret = conn.prepareStatement(UPDATE_TAGS);
ret.setObject(1, conn.createArrayOf("text", PlowUtils.uniquify(tags)));
ret.setObject(2, layer.getLayerId());
return ret;
}
});
}
}