/** * Obtain the loaded value now. */ @Override public T now() { return result.now(); }
@Override public T apply(Result<T> input) { return input.now(); } }
@Override public Object invoke(Object obj, Method meth, Object[] params) throws Throwable { return meth.invoke(result.now(), params); }
@Override final protected T translate(final Result<F> from) { return wrap(from.now()); } }
@Override @SuppressWarnings("unchecked") public T nowUncached() { // Because clients could conceivably get() in the middle of our operations (see LoadCollectionRefsTest.specialListWorks()), // we need to check for early execution. This will perform poorly, but at least it will work. //assert Round.this.isExecuted(); loadEngine.execute(); return (T)translated.now().get(key); }
private Object writeReplace() throws ObjectStreamException { return new NowProxy<>(result.now()); }
@Override public Response commit() { // Complete any enlisted operations so that the session becomes consistent. Note that some of the // enlisted load operations might result in further enlistment... so we have to do this in a loop // that protects against concurrent modification exceptions while (!enlisted.isEmpty()) { final List<Result<?>> last = enlisted; enlisted = new ArrayList<>(); for (final Result<?> result: last) result.now(); } final Response response = transaction.commit(); afterCommit.run(); return response; }
/** */ @Override public Map<Key<?>, Object> nowUncached() { final Map<Key<?>, Object> result = new HashMap<>(raw.now().size() * 2); ctx = new LoadContext(LoadEngine.this); for (final Entity ent: raw.now().values()) { final Key<?> key = Key.create(ent.getKey()); final Object entity = load(ent, ctx); result.put(key, entity); } return result; }
/** Loads them; note that it's possible for some loaded results to be null */ private Iterator<ResultWithCursor<T>> load(final Iterator<ResultWithCursor<Key<T>>> keys) { final List<Entry<ResultWithCursor<Key<T>>, Result<T>>> results = Lists.newArrayList(); while (keys.hasNext()) { final ResultWithCursor<Key<T>> next = keys.next(); results.add(Maps.immutableEntry(next, loadEngine.load(next.getResult()))); } loadEngine.execute(); return Iterators.transform(results.iterator(), entry -> new ResultWithCursor<>(entry.getValue().now(), entry.getKey().getCursorAfter())); }
/** Possibly pulls some values from the stuffed collection */ private Result<Map<com.google.cloud.datastore.Key, Entity>> fetchPending() { // We don't need to fetch anything that has been stuffed final Map<com.google.cloud.datastore.Key, Entity> combined = new HashMap<>(); Set<com.google.cloud.datastore.Key> fetch = new HashSet<>(); for (com.google.cloud.datastore.Key key: pending) { Entity ent = stuffed.get(key); if (ent == null) fetch.add(key); else combined.put(key, ent); } if (fetch.isEmpty()) { return new ResultNow<>(combined); } else { final Result<Map<com.google.cloud.datastore.Key, Entity>> fetched = loadEngine.fetch(fetch); return () -> { combined.putAll(fetched.now()); return combined; }; } }
@Override public <E> E now(final Key<E> key) { return createLoadEngine().load(key).now(); }
public void flush() { final List<Result<?>> futures = new ArrayList<>(); // Need to do this in a loop because @OnSave methods can enlist more deferred operations. Execution // of save or delete will undefer() all the relevant items, so both lists empty mean we're done. while (!operations.isEmpty() || !autogeneratedIdSaves.isEmpty()) { // Sort into two batch operations: one for save, one for delete. final List<Object> saves = new ArrayList<>(); final List<Key<?>> deletes = new ArrayList<>(); for (final Map.Entry<Key<?>, Object> entry : operations.entrySet()) { if (entry.getValue() == null) deletes.add(entry.getKey()); else saves.add(entry.getValue()); } saves.addAll(autogeneratedIdSaves); if (!saves.isEmpty()) futures.add(ofy.save().entities(saves)); if (!deletes.isEmpty()) futures.add(ofy.delete().keys(deletes)); } // Complete any pending operations for (final Result<?> future : futures) { future.now(); } }
/** Turn this into a result set */ public void execute() { if (needsExecution()) { log.trace("Executing round: {}", pending); Result<Map<com.google.cloud.datastore.Key, Entity>> fetched = fetchPending(); translated = loadEngine.translate(fetched); // If we're in a transaction (and beyond the first round), force all subsequent rounds to complete. // This effectively means that only the first round can be asynchronous; all other rounds are // materialized immediately. The reason for this is that there are some nasty edge cases with @Load // annotations in transactions getting called after the transaction closes. This is possibly not the // best solution to the problem, but it solves the problem now. if (loadEngine.ofy.getTransaction() != null && depth > 0) translated.now(); } }
T thing = sv.getResult().now(); if (thing != null) { SaveContext saveCtx = new SaveContext() {
@Override protected void migrateEntity(Key<FeedbackResponseComment> entity) { FeedbackResponseComment comment = ofy().load().key(entity).now(); comment.setCommentGiverType(FeedbackParticipantType.INSTRUCTORS); comment.setIsCommentFromFeedbackParticipant(false); ofy().save().entity(comment).now(); } }
@Override public Void complete() { ofyDelete.now(); if (searchDelete != null) { searchDelete.complete(); } return null; } };
@Override protected void migrateEntity(Key<Course> key) throws Exception { Course course = ofy().load().key(key).now(); course.setName(SanitizationHelper.desanitizeIfHtmlSanitized(course.getName())); ofy().save().entity(course).now(); } }
@Override protected void migrateEntity(Key<Instructor> key) throws Exception { Instructor instructor = ofy().load().key(key).now(); instructor.setDisplayedName(SanitizationHelper.desanitizeIfHtmlSanitized(instructor.getDisplayedName())); ofy().save().entity(instructor).now(); } }
ofy().save().entities(oldStudents).now(); ofy().save().entities(oldInstructors).now(); instructorsDb.putDocuments( oldInstructors.stream().map(InstructorAttributes::valueOf).collect(Collectors.toList())); ofy().save().entity(oldAccount).now(); } else { println(String.format("Skip creation of new account as account (%s) already exists", newGoogleId)); ofy().delete().type(Account.class).id(oldGoogleId).now(); ofy().save().entity(oldStudentProfile).now(); ofy().delete().key(oldStudentProfileKey).now();
@Override protected void migrateEntity(Key<CourseStudent> key) throws Exception { CourseStudent student = ofy().load().key(key).now(); student.setComments(SanitizationHelper.desanitizeIfHtmlSanitized(student.getComments())); student.setName(SanitizationHelper.desanitizeIfHtmlSanitized(student.getName())); student.setLastName(SanitizationHelper.desanitizeIfHtmlSanitized(student.getLastName())); ofy().save().entity(student).now(); } }