package org.akvo.gae.remoteapi;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.gallatinsystems.surveyal.domain.SurveyedLocale;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;
/**
* Loop through all the SurveyedLocales and 1) Generate an identifier if it does
* not exist 2) Find and set the surveyGroupId if it does not exist
*
* @author jonasenlund
*
*/
public class SurveyedLocaleFix implements Process {
final static Map<Long, Long> formIdToSurveyIdCache = new HashMap<>();
@Override
public void execute(DatastoreService ds, String[] args) throws Exception {
Query surveyedLocaleQuery = new Query("SurveyedLocale");
Set<Entity> updatedEntities = new HashSet<>();
for (Entity surveyedLocale : ds.prepare(surveyedLocaleQuery)
.asIterable(FetchOptions.Builder.withChunkSize(500))) {
Long surveyedLocaleId = surveyedLocale.getKey().getId();
boolean updated = false;
Object identifier = surveyedLocale.getProperty("identifier");
if (identifier == null) {
String newIdentifier = SurveyedLocale.generateBase32Uuid();
surveyedLocale.setProperty("identifier", newIdentifier);
System.out.println("Successfully derived identifier for "
+ surveyedLocaleId);
updated = true;
}
Long surveyId = (Long) surveyedLocale.getProperty("surveyGroupId");
if (surveyId == null) {
surveyId = findSurveyIdByCreationFormId(ds,
(Long) surveyedLocale.getProperty("creationSurveyId"));
if (surveyId == null) {
surveyId = findSurveyIdByLastSurveyalInstanceId(ds,
(Long) surveyedLocale
.getProperty("lastSurveyalInstanceId"));
if (surveyId != null) {
System.out
.println("Successfully derived surveyId via lastSurveyalInstanceId for "
+ surveyedLocaleId);
}
} else {
System.out
.println("Successfully derived surveyId via creationSurveyId for "
+ surveyedLocaleId);
}
if (surveyId == null) {
System.out.println("Could not derive surveyId for "
+ surveyedLocaleId);
} else {
surveyedLocale.setProperty("surveyGroupId", surveyId);
updated = true;
}
}
if (updated) {
updatedEntities.add(surveyedLocale);
}
}
if (!updatedEntities.isEmpty()) {
ds.put(updatedEntities);
System.out.println(String.format("Updated %s entities",
updatedEntities.size()));
}
}
public static Long findSurveyIdByCreationFormId(DatastoreService ds,
Long creationFormId) {
if (creationFormId == null) {
return null;
}
return findSurveyIdByFormId(ds, creationFormId);
}
public static Long findSurveyIdByLastSurveyalInstanceId(
DatastoreService ds, Long lastSurveyalInstanceId) {
if (lastSurveyalInstanceId == null) {
return null;
}
Filter surveyInstanceByIdFilter = new FilterPredicate(
Entity.KEY_RESERVED_PROPERTY, FilterOperator.EQUAL,
KeyFactory.createKey("SurveyInstance",
(Long) lastSurveyalInstanceId));
Query surveyInstanceQuery = new Query("SurveyInstance")
.setFilter(surveyInstanceByIdFilter);
Entity surveyInstance = ds.prepare(surveyInstanceQuery)
.asSingleEntity();
if (surveyInstance == null) {
return null;
}
return findSurveyIdByFormId(ds,
(Long) surveyInstance.getProperty("surveyId"));
}
public static Long findSurveyIdByFormId(DatastoreService ds, Long formId) {
if (formId == null) {
return null;
}
if (formIdToSurveyIdCache.containsKey(formId)) {
return formIdToSurveyIdCache.get(formId);
}
Filter formByIdFilter = new FilterPredicate(
Entity.KEY_RESERVED_PROPERTY, FilterOperator.EQUAL,
KeyFactory.createKey("Survey", (Long) formId));
Query formQuery = new Query("Survey").setFilter(formByIdFilter);
Entity form = ds.prepare(formQuery).asSingleEntity();
if (form == null) {
return null;
}
Long surveyId = (Long) form.getProperty("surveyGroupId");
if (surveyId != null) {
formIdToSurveyIdCache.put(formId, surveyId);
}
return surveyId;
}
}