Jason,
Any way you can send me the code for the blog manipulation? As it sounds as a time consuming excercise.
I solved the same problem by using an Interceptor, but your solution sounds more elegant.
Code:
package bah.metadata.hibernate;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class MetadataInterceptor extends EmptyInterceptor {
private static final long serialVersionUID = -2149963919888842054L;
private Log log = LogFactory.getLog(MetadataInterceptor.class);
/*
* (non-Javadoc)
*
* @see org.hibernate.Interceptor#onPrepareStatement(java.lang.String)
* Handles MySQL GIS TYPES if new columns are added add them to the
* GIS_COLUMNS array
*/
public static Map<String, String> storedSql = new HashMap<String, String>();
public static String[] GIS_COLUMNS = { "location", "coverage" };
public static String[] EXCEPTION_FLAGS = { "Within", "Contains" };
@Override
public String onPrepareStatement(String sql) {
String newSql = sql;
String foundSql = storedSql.get(sql);
if (foundSql != null) {
newSql = foundSql;
} else {
int tokenCounter = 0;
//ignore clauses
Map<String,String> clauses = new HashMap<String,String>();
for (String keyWord: EXCEPTION_FLAGS){
if (StringUtils.contains(newSql,keyWord)){
String token = StringUtils.substringBetween(newSql, keyWord + "(", ")");
token = keyWord + "(" + token +")";
String key = "token" + tokenCounter++;
clauses.put(key, token);
newSql = StringUtils.replace(newSql, token, key);
}
}
if (StringUtils.contains(sql, "select") || StringUtils.contains(sql, "Select") || StringUtils.contains(sql, "SELECT")) {
for (String field : GIS_COLUMNS) {
if (StringUtils.contains(newSql, field)) {
String tableName = StringUtils.substringAfterLast(
StringUtils.substringBeforeLast(newSql, "."
+ field), " ");
String fullField = tableName + "." + field;
newSql = StringUtils.replace(newSql, fullField,
"AsText(" + fullField + ")");
}
}
} else if (StringUtils.contains(sql, "insert") || StringUtils.contains(sql, "Insert") || StringUtils.contains(sql, "INSERT")) {
for (String field : GIS_COLUMNS) {
if (StringUtils.contains(newSql, field)) {
int pos = StringUtils.countMatches(StringUtils
.substringBefore(newSql, field), ",");
String[] args = StringUtils.split(newSql, ",");
args[2 * pos] = "GeomFromText(?)";
if (2 * pos == args.length - 1) {
args[2 * pos] += ")";
}
newSql = StringUtils.join(args, ",");
}
}
} else if (StringUtils.contains(sql, "update") || StringUtils.contains(sql, "Update") || StringUtils.contains(sql, "UPDATE")) {
for (String field : GIS_COLUMNS) {
if (StringUtils.contains(newSql, field)) {
newSql = StringUtils.replace(newSql, field + "=?",
field + " = GeomFromText(?)");
}
}
}
for (int i = 0; i < tokenCounter; i++){
String key = "token" + i;
newSql = StringUtils.replace(newSql, key, clauses.get(key));
}
storedSql.put(sql, newSql);
log.debug(newSql);
}
return newSql;
}
}