Search in sources :

Example 71 with Key

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;
}
Also used : Field(java.lang.reflect.Field) HashMap(java.util.HashMap) SienaRestrictedApiException(siena.SienaRestrictedApiException) QueryJoin(siena.QueryJoin) ArrayList(java.util.ArrayList) Key(com.google.appengine.api.datastore.Key)

Example 72 with Key

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;
}
Also used : Matcher(java.util.regex.Matcher) ArrayList(java.util.ArrayList) QueryFilterSearch(siena.QueryFilterSearch) Field(java.lang.reflect.Field) QueryFilterSimple(siena.QueryFilterSimple) ArrayList(java.util.ArrayList) List(java.util.List) SienaException(siena.SienaException) Pattern(java.util.regex.Pattern) SienaException(siena.SienaException) SienaRestrictedApiException(siena.SienaRestrictedApiException) QueryOrder(siena.QueryOrder) FilterOperator(com.google.appengine.api.datastore.Query.FilterOperator) QueryOwned(siena.QueryOwned) QueryFilter(siena.QueryFilter) QueryFilterEmbedded(siena.core.QueryFilterEmbedded) Collection(java.util.Collection) Id(siena.Id) Key(com.google.appengine.api.datastore.Key)

Example 73 with Key

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);
    }
}
Also used : Entity(com.google.appengine.api.datastore.Entity) SienaException(siena.SienaException) Key(com.google.appengine.api.datastore.Key) SienaException(siena.SienaException) EntityNotFoundException(com.google.appengine.api.datastore.EntityNotFoundException) ClassInfo(siena.ClassInfo)

Example 74 with Key

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;
}
Also used : Entity(com.google.appengine.api.datastore.Entity) ArrayList(java.util.ArrayList) Key(com.google.appengine.api.datastore.Key) ClassInfo(siena.ClassInfo)

Example 75 with Key

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;
}
Also used : Entity(com.google.appengine.api.datastore.Entity) Field(java.lang.reflect.Field) Key(com.google.appengine.api.datastore.Key) ClassInfo(siena.ClassInfo)

Aggregations

Key (com.google.appengine.api.datastore.Key)121 Entity (com.google.appengine.api.datastore.Entity)83 ArrayList (java.util.ArrayList)39 DatastoreService (com.google.appengine.api.datastore.DatastoreService)26 Query (com.google.appengine.api.datastore.Query)23 Test (org.junit.Test)23 ClassInfo (siena.ClassInfo)23 Field (java.lang.reflect.Field)22 EntityNotFoundException (com.google.appengine.api.datastore.EntityNotFoundException)21 HashMap (java.util.HashMap)14 SienaException (siena.SienaException)14 List (java.util.List)13 PreparedQuery (com.google.appengine.api.datastore.PreparedQuery)12 QueryResultList (com.google.appengine.api.datastore.QueryResultList)11 Map (java.util.Map)11 Transaction (com.google.appengine.api.datastore.Transaction)9 SienaFutureContainer (siena.core.async.SienaFutureContainer)9 SienaFutureWrapper (siena.core.async.SienaFutureWrapper)9 FilterPredicate (com.google.appengine.api.datastore.Query.FilterPredicate)7 IOException (java.io.IOException)7