use of com.google.appengine.api.datastore.Key in project siena by mandubian.
the class GaeQueryUtils method buildJoinFieldKeysMap.
public static <T> Map<Field, ArrayList<Key>> buildJoinFieldKeysMap(QueryData<T> query) {
List<QueryJoin> joins = query.getJoins();
// join queries
Map<Field, ArrayList<Key>> fieldMap = new HashMap<Field, ArrayList<Key>>();
for (QueryJoin join : joins) {
Field field = join.field;
if (!ClassInfo.isModel(field.getType())) {
throw new SienaRestrictedApiException(GaePersistenceManager.DB, "join", "Join not possible: Field " + field.getName() + " is not a relation field");
} else if (join.sortFields != null && join.sortFields.length != 0)
throw new SienaRestrictedApiException(GaePersistenceManager.DB, "join", "Join not allowed with sort fields");
fieldMap.put(field, new ArrayList<Key>());
}
// join annotations
for (Field field : ClassInfo.getClassInfo(query.getQueriedClass()).joinFields) {
fieldMap.put(field, new ArrayList<Key>());
}
return fieldMap;
}
use of com.google.appengine.api.datastore.Key in project siena by mandubian.
the class GaeQueryUtils method addFiltersOrders.
public static <T> com.google.appengine.api.datastore.Query addFiltersOrders(QueryData<T> query, com.google.appengine.api.datastore.Query q, Key parentKey) {
List<QueryFilter> filters = query.getFilters();
for (QueryFilter filter : filters) {
if (QueryFilterSimple.class.isAssignableFrom(filter.getClass())) {
QueryFilterSimple qf = (QueryFilterSimple) filter;
Field f = qf.field;
String propertyName = ClassInfo.getColumnNames(f)[0];
Object value = qf.value;
FilterOperator op = operators.get(qf.operator);
// IN and NOT_EQUAL doesn't allow to use cursors
if (op == FilterOperator.IN || op == FilterOperator.NOT_EQUAL) {
QueryOptionGaeContext gaeCtx = (QueryOptionGaeContext) query.option(QueryOptionGaeContext.ID);
if (gaeCtx == null) {
gaeCtx = new QueryOptionGaeContext();
query.options().put(gaeCtx.type, gaeCtx);
}
gaeCtx.useCursor = false;
query.option(QueryOptionOffset.ID).activate();
}
if (value != null && ClassInfo.isModel(value.getClass())) {
Key key = GaeMappingUtils.getKey(value);
q.addFilter(propertyName, op, key);
} else {
if (ClassInfo.isId(f)) {
Id id = f.getAnnotation(Id.class);
switch(id.value()) {
case NONE:
if (value != null) {
if (!Collection.class.isAssignableFrom(value.getClass())) {
// long or string goes toString
Key key;
if (parentKey == null) {
key = KeyFactory.createKey(q.getKind(), value.toString());
} else {
key = KeyFactory.createKey(parentKey, q.getKind(), value.toString());
}
q.addFilter(Entity.KEY_RESERVED_PROPERTY, op, key);
} else {
List<Key> keys = new ArrayList<Key>();
for (Object val : (Collection<?>) value) {
if (parentKey == null) {
keys.add(KeyFactory.createKey(q.getKind(), val.toString()));
} else {
keys.add(KeyFactory.createKey(parentKey, q.getKind(), val.toString()));
}
}
q.addFilter(Entity.KEY_RESERVED_PROPERTY, op, keys);
}
}
break;
case AUTO_INCREMENT:
if (value != null) {
if (!Collection.class.isAssignableFrom(value.getClass())) {
Key key;
Class<?> type = f.getType();
if (Long.TYPE == type || Long.class.isAssignableFrom(type)) {
if (parentKey == null) {
key = KeyFactory.createKey(q.getKind(), (Long) value);
} else {
key = KeyFactory.createKey(parentKey, q.getKind(), (Long) value);
}
} else {
if (parentKey == null) {
key = KeyFactory.createKey(q.getKind(), value.toString());
} else {
key = KeyFactory.createKey(parentKey, q.getKind(), value.toString());
}
}
q.addFilter(Entity.KEY_RESERVED_PROPERTY, op, key);
} else {
List<Key> keys = new ArrayList<Key>();
for (Object val : (Collection<?>) value) {
if (value instanceof String)
val = Long.parseLong((String) val);
if (parentKey == null) {
keys.add(KeyFactory.createKey(q.getKind(), (Long) val));
} else {
keys.add(KeyFactory.createKey(parentKey, q.getKind(), (Long) val));
}
}
q.addFilter(Entity.KEY_RESERVED_PROPERTY, op, keys);
}
}
break;
case UUID:
if (value != null) {
if (!Collection.class.isAssignableFrom(value.getClass())) {
// long or string goes toString
Key key;
if (parentKey == null) {
key = KeyFactory.createKey(q.getKind(), value.toString());
} else {
key = KeyFactory.createKey(parentKey, q.getKind(), value.toString());
}
q.addFilter(Entity.KEY_RESERVED_PROPERTY, op, key);
} else {
List<Key> keys = new ArrayList<Key>();
for (Object val : (Collection<?>) value) {
keys.add(KeyFactory.createKey(q.getKind(), val.toString()));
}
q.addFilter(Entity.KEY_RESERVED_PROPERTY, op, keys);
}
}
break;
default:
throw new SienaException("Id Generator " + id.value() + " not supported");
}
} else if (Enum.class.isAssignableFrom(f.getType())) {
value = value.toString();
q.addFilter(propertyName, op, value);
} else {
q.addFilter(propertyName, op, value);
}
}
} else if (QueryFilterSearch.class.isAssignableFrom(filter.getClass())) {
Class<T> clazz = query.getQueriedClass();
QueryFilterSearch qf = (QueryFilterSearch) filter;
if (qf.fields.length > 1)
throw new SienaException("Search not possible for several fields in GAE: only one field");
try {
Field field = Util.getField(clazz, qf.fields[0]);
if (field.isAnnotationPresent(Unindexed.class)) {
throw new SienaException("Cannot search the @Unindexed field " + field.getName());
}
// cuts match into words
String[] words = qf.match.split("\\s");
// if several words, then only OR operator represented by IN GAE
Pattern pNormal = Pattern.compile("[^\\*](\\w+)[^\\*]");
if (words.length > 1) {
for (String word : words) {
if (!pNormal.matcher(word).matches()) {
throw new SienaException("Cannot do a multiwords search with the * operator");
}
}
List<String> wordList = new ArrayList<String>();
Collections.addAll(wordList, words);
addSearchFilterIn(q, field, wordList);
} else {
// searches for pattern such as "alpha*" or "*alpha" or "alpha"
Pattern pStart = Pattern.compile("(\\w+)\\*");
String word = words[0];
Matcher matcher = pStart.matcher(word);
if (matcher.matches()) {
String realWord = matcher.group(1);
addSearchFilterBeginsWith(q, field, realWord);
continue;
}
matcher = pNormal.matcher(word);
if (matcher.matches()) {
addSearchFilterEquals(q, field, word);
continue;
}
Pattern pEnd = Pattern.compile("\\*(\\w+)");
matcher = pEnd.matcher(word);
if (matcher.matches()) {
throw new SienaException("Cannot do a \"*word\" search in GAE");
}
}
} catch (Exception e) {
throw new SienaException(e);
}
break;
} else if (QueryFilterEmbedded.class.isAssignableFrom(filter.getClass())) {
QueryFilterEmbedded qf = (QueryFilterEmbedded) filter;
String propName = "";
int sz = qf.fields.size();
for (int i = 0; i < sz; i++) {
propName += ClassInfo.getSingleColumnName(qf.fields.get(i));
if (i < sz - 1) {
propName += qf.fieldSeparator;
}
}
Object value = qf.value;
FilterOperator op = operators.get(qf.operator);
// IN and NOT_EQUAL doesn't allow to use cursors
if (op == FilterOperator.IN || op == FilterOperator.NOT_EQUAL) {
QueryOptionGaeContext gaeCtx = (QueryOptionGaeContext) query.option(QueryOptionGaeContext.ID);
if (gaeCtx == null) {
gaeCtx = new QueryOptionGaeContext();
query.options().put(gaeCtx.type, gaeCtx);
}
gaeCtx.useCursor = false;
query.option(QueryOptionOffset.ID).activate();
}
q.addFilter(propName, op, value);
}
}
// adds filter on owners
List<QueryOwned> ownees = query.getOwnees();
for (QueryOwned ownee : ownees) {
String propertyName = ClassInfo.getSimplestColumnName(ownee.field);
FilterOperator op = operators.get("=");
Key key = GaeMappingUtils.getKey(ownee.owner);
q.addFilter(propertyName, op, key);
}
List<QueryOrder> orders = query.getOrders();
for (QueryOrder order : orders) {
Field f = order.field;
if (ClassInfo.isId(f)) {
q.addSort(Entity.KEY_RESERVED_PROPERTY, order.ascending ? SortDirection.ASCENDING : SortDirection.DESCENDING);
} else {
q.addSort(ClassInfo.getColumnNames(f)[0], order.ascending ? SortDirection.ASCENDING : SortDirection.DESCENDING);
}
}
return q;
}
use of com.google.appengine.api.datastore.Key in project siena by mandubian.
the class GaePersistenceManager method get.
public void get(Object obj) {
Key key = GaeMappingUtils.getKey(obj);
ClassInfo info = ClassInfo.getClassInfo(obj.getClass());
try {
Entity entity = ds.get(key);
if (entity != null) {
GaeMappingUtils.fillModel(obj, entity);
// related fields (Many<T> management mainly)
if (!info.ownedFields.isEmpty()) {
mapOwned(obj);
}
// aggregated management
if (!info.aggregatedFields.isEmpty()) {
mapAggregated(obj);
}
// join management
if (!info.joinFields.isEmpty()) {
mapJoins(obj);
}
}
} catch (Exception e) {
throw new SienaException(e);
}
}
use of com.google.appengine.api.datastore.Key in project siena by mandubian.
the class GaePersistenceManager method getByKeys.
public <T> List<T> getByKeys(Class<T> clazz, Iterable<?> keys) {
List<Key> gaeKeys = new ArrayList<Key>();
ClassInfo info = ClassInfo.getClassInfo(clazz);
for (Object key : keys) {
gaeKeys.add(GaeMappingUtils.makeKeyFromId(clazz, key));
}
Map<Key, Entity> entityMap = ds.get(gaeKeys);
List<T> models = new ArrayList<T>(entityMap.size());
for (Object key : keys) {
Entity entity = entityMap.get(GaeMappingUtils.makeKeyFromId(clazz, key));
T obj = null;
if (entity != null) {
obj = GaeMappingUtils.mapEntity(entity, clazz);
if (obj != null) {
// related fields (Many<T> management mainly)
if (!info.ownedFields.isEmpty()) {
mapOwned(obj);
}
// aggregated management
if (!info.aggregatedFields.isEmpty()) {
mapAggregated(obj);
}
// join management
if (!info.joinFields.isEmpty()) {
mapJoins(obj);
}
}
}
models.add(obj);
}
return models;
}
use of com.google.appengine.api.datastore.Key in project siena by mandubian.
the class GaePersistenceManager method _updateManageMaps.
private int _updateManageMaps(HashMap<PersistenceType, List<Entity>> entitiesMap, HashMap<PersistenceType, List<Object>> objectsMap, HashMap<PersistenceType, List<Key>> keysMap) {
int nb = 0;
// saves the updated owned objects
List<Object> objs = objectsMap.get(PersistenceType.SAVE);
if (objs != null && !objs.isEmpty()) {
nb += save(objs);
}
// saves the updated aggregated objects
List<Entity> entities = entitiesMap.get(PersistenceType.INSERT);
if (entities != null && !entities.isEmpty()) {
List<Key> generatedKeys = ds.put(entities);
int i = 0;
for (Object elt : objectsMap.get(PersistenceType.INSERT)) {
Class<?> clazz = elt.getClass();
ClassInfo info = ClassInfo.getClassInfo(clazz);
Field idField = info.getIdField();
GaeMappingUtils.setIdFromKey(idField, elt, generatedKeys.get(i));
}
nb += generatedKeys.size();
}
// saves the updated aggregated objects
entities = entitiesMap.get(PersistenceType.UPDATE);
if (entities != null && !entities.isEmpty()) {
ds.put(entitiesMap.get(PersistenceType.UPDATE));
nb += entities.size();
}
// removes the deleted aggregated objects
List<Key> keys = keysMap.get(PersistenceType.DELETE);
if (keys != null && !keys.isEmpty()) {
ds.delete(keys);
nb += keys.size();
}
return nb;
}
Aggregations