use of siena.SienaException in project siena by mandubian.
the class GaePersistenceManager method prepare.
private <T> PreparedQuery prepare(Query<T> query) {
Class<?> clazz = query.getQueriedClass();
ClassInfo info = ClassInfo.getClassInfo(clazz);
com.google.appengine.api.datastore.Query q;
// manages aggregation at first
List<QueryAggregated> aggregs = query.getAggregatees();
if (aggregs.isEmpty()) {
q = new com.google.appengine.api.datastore.Query(info.tableName);
return ds.prepare(GaeQueryUtils.addFiltersOrders(query, q));
} else if (aggregs.size() == 1) {
QueryAggregated aggreg = aggregs.get(0);
Key ancestorKey = GaeMappingUtils.getKey(aggreg.aggregator);
q = new com.google.appengine.api.datastore.Query(GaeMappingUtils.getKindWithAncestorField(info, ClassInfo.getClassInfo(aggreg.aggregator.getClass()), aggreg.field));
q.setAncestor(ancestorKey);
return ds.prepare(GaeQueryUtils.addFiltersOrders(query, q, ancestorKey));
} else {
throw new SienaException("Only one aggregation per query allowed");
}
}
use of siena.SienaException in project siena by mandubian.
the class H2PersistenceManager method doSearch.
protected <T> List<T> doSearch(Query<T> query, int limit, int offset) {
// TODO this is a very raw impl: need some work certainly
try {
Connection conn = this.getConnection();
ClassInfo ci = ClassInfo.getClassInfo(query.getQueriedClass());
// doesn't index a table that has already been indexed
if (!tableIndexMap.containsKey(ci.tableName)) {
List<String> colList = ci.getUpdateFieldsColumnNames();
String cols = null;
if (!colList.isEmpty()) {
cols = "";
// removes auto generated IDs from index
int sz = colList.size();
for (int i = 0; i < sz; i++) {
if ("h2".equals(dbMode))
cols += colList.get(i).toUpperCase();
else // !!! mysql mode means case INsensitive to lowercase !!!!
if ("mysql".equals(dbMode))
cols += colList.get(i).toLowerCase();
else
cols += colList.get(i).toUpperCase();
if (i < sz - 1)
cols += ",";
}
}
// creates the index
FullText.createIndex(conn, "PUBLIC", ci.tableName.toUpperCase(), cols);
tableIndexMap.put(ci.tableName, true);
}
String searchString = "";
Iterator<QueryFilterSearch> it = query.getSearches().iterator();
boolean first = true;
while (it.hasNext()) {
if (!first) {
searchString += " ";
} else {
first = false;
}
searchString += it.next().match;
}
ResultSet rs = FullText.searchData(conn, searchString, limit, offset);
List<T> res = new ArrayList<T>();
Field idField = ci.getIdField();
Class<?> idClass = idField.getType();
while (rs.next()) {
// String queryStr = rs.getString("QUERY");
// String score = rs.getString("SCORE");
// Array columns = rs.getArray("COLUMNS");
Object[] keys = (Object[]) rs.getArray("KEYS").getArray();
// convert keys into real type if the key is not a string
Object[] realKeys = null;
if (idField.getType() != String.class) {
realKeys = new Object[keys.length];
for (int i = 0; i < keys.length; i++) {
realKeys[i] = Util.fromString(idClass, (String) keys[i]);
}
} else {
realKeys = keys;
}
if (res == null)
res = this.getByKeys(query.getQueriedClass(), realKeys);
else
res.addAll(this.getByKeys(query.getQueriedClass(), realKeys));
}
return res;
} catch (SQLException e) {
throw new SienaException(e);
}
}
use of siena.SienaException in project siena by mandubian.
the class JdbcDBUtils method buildSqlSelect.
public static <T> StringBuilder buildSqlSelect(Query<T> query) {
Class<T> clazz = query.getQueriedClass();
JdbcClassInfo info = JdbcClassInfo.getClassInfo(clazz);
List<String> cols = new ArrayList<String>();
List<Field> joinFields = JdbcMappingUtils.getJoinFields(query, info);
if (joinFields == null) {
JdbcClassInfo.calculateColumnsAliases(info.allFields, cols, info.tableName, "");
StringBuilder sql = new StringBuilder("SELECT " + Util.join(cols, ", ") + " FROM " + info.tableName);
return sql;
}
// builds fields from primary class
JdbcClassInfo.calculateColumnsAliases(info.allFields, cols, info.tableName, "");
StringBuilder sql = new StringBuilder(" FROM " + info.tableName);
int i = 0;
String alias;
for (Field field : joinFields) {
JdbcClassInfo fieldInfo = JdbcClassInfo.getClassInfo(field.getType());
if (!ClassInfo.isModel(field.getType())) {
throw new SienaException("Join not possible: Field " + field.getName() + " is not a relation field");
}
alias = fieldInfo.tableName + i++;
fieldInfo.joinFieldAliases.put(field.getName(), alias);
// DO NOT remove the field itself from columns because it allows to find NULL fields
// cols.remove( info.tableName+"."+field.getName());
// adds all field columns using Alias
JdbcClassInfo.calculateColumnsAliases(fieldInfo.allFields, cols, alias, "");
String[] columns = ClassInfo.getColumnNames(field, info.tableName);
if (columns.length > 1 || fieldInfo.keys.size() > 1) {
throw new SienaException("Join not possible: join field " + field.getName() + " has multiple keys");
}
// LEFT INNER JOIN TO GET NULL FIELDS
sql.append(" LEFT JOIN " + fieldInfo.tableName + " AS " + alias + " ON " + columns[0] + " = " + alias + "." + fieldInfo.keys.get(0).getName());
}
sql.insert(0, "SELECT " + Util.join(cols, ", "));
return sql;
}
use of siena.SienaException in project siena by mandubian.
the class JdbcPersistenceManager method appendSqlWhere.
public <T> void appendSqlWhere(Query<T> query, StringBuilder sql, List<Object> parameters) {
Class<T> clazz = query.getQueriedClass();
JdbcClassInfo info = JdbcClassInfo.getClassInfo(clazz);
List<QueryFilter> filters = query.getFilters();
if (filters.isEmpty()) {
return;
}
sql.append(JdbcDBUtils.WHERE);
boolean first = true;
for (QueryFilter filter : filters) {
if (QueryFilterSimple.class.isAssignableFrom(filter.getClass())) {
QueryFilterSimple qf = (QueryFilterSimple) filter;
String op = qf.operator;
Object value = qf.value;
Field f = qf.field;
if (!first) {
sql.append(JdbcDBUtils.AND);
}
first = false;
String[] columns = ClassInfo.getColumnNames(f, info.tableName);
if ("IN".equals(op)) {
if (!Collection.class.isAssignableFrom(value.getClass()))
throw new SienaException("Collection needed when using IN operator in filter() query");
StringBuilder s = new StringBuilder();
Collection<?> col = (Collection<?>) value;
for (Object object : col) {
// TODO: if object isModel
parameters.add(object);
s.append(",?");
}
sql.append(columns[0] + " IN(" + s.toString().substring(1) + ")");
} else if (ClassInfo.isModel(f.getType())) {
if (!op.equals("=")) {
throw new SienaException("Unsupported operator for relationship: " + op);
}
JdbcClassInfo classInfo = JdbcClassInfo.getClassInfo(f.getType());
int i = 0;
JdbcMappingUtils.checkForeignKeyMapping(classInfo.keys, columns, query.getQueriedClass(), f);
for (Field key : classInfo.keys) {
if (value == null) {
sql.append(columns[i++] + JdbcDBUtils.IS_NULL);
} else {
sql.append(columns[i++] + "=?");
key.setAccessible(true);
Object o;
try {
o = key.get(value);
parameters.add(o);
} catch (Exception e) {
throw new SienaException(e);
}
}
}
} else {
if (value == null && op.equals("=")) {
sql.append(columns[0] + JdbcDBUtils.IS_NULL);
} else if (value == null && op.equals("!=")) {
sql.append(columns[0] + JdbcDBUtils.IS_NOT_NULL);
} else {
sql.append(columns[0] + op + "?");
if (value == null) {
parameters.add(Types.NULL);
} else {
if (value instanceof Date) {
value = Util.translateDate(f, (Date) value);
} else if (value instanceof Enum) {
value = value.toString();
}
parameters.add(value);
}
}
}
} else if (QueryFilterSearch.class.isAssignableFrom(filter.getClass())) {
// TODO MYSQL implementation manages only 1 search in a query
if (query.getSearches().size() > 1) {
throw new SienaRestrictedApiException(DB, "search", "MySQL implementation manages only on single search at a time in a query");
}
// adds querysearch
QueryFilterSearch qf = (QueryFilterSearch) filter;
appendSqlSearch(qf, clazz, info, sql, parameters);
}
}
}
use of siena.SienaException in project siena by mandubian.
the class JdbcPersistenceManager method get.
public <T> int get(Iterable<T> objects) {
Map<JdbcClassInfo, List<Object>> objMap = new HashMap<JdbcClassInfo, List<Object>>();
PreparedStatement ps = null;
for (Object obj : objects) {
JdbcClassInfo classInfo = JdbcClassInfo.getClassInfo(obj.getClass());
if (!objMap.containsKey(classInfo)) {
List<Object> l = new ArrayList<Object>();
l.add(obj);
objMap.put(classInfo, l);
} else {
objMap.get(classInfo).add(obj);
}
}
int total = 0;
try {
for (JdbcClassInfo classInfo : objMap.keySet()) {
// doesn't manage multiple keys case
if (classInfo.keys.size() > 1) {
throw new SienaException("Can't batch select multiple keys objects");
}
Field f = classInfo.keys.get(0);
HashMap<Object, Object> keyObj = new HashMap<Object, Object>();
for (Object obj : objMap.get(classInfo)) {
Object key = Util.readField(obj, f);
keyObj.put(key, obj);
}
Query<?> q = createQuery(classInfo.info.clazz);
List<?> results = q.filter(f.getName() + " IN", keyObj.keySet()).fetch();
for (Object res : results) {
Object resKey = Util.readField(res, f);
Util.copyObject(res, keyObj.get(resKey));
}
total += results.size();
}
return total;
} catch (SienaException e) {
throw e;
} catch (Exception e) {
throw new SienaException(e);
} finally {
JdbcDBUtils.closeStatementAndConnection(this, ps);
}
}
Aggregations