package org.commcare.utils;
import android.support.annotation.NonNull;
import org.commcare.CommCareApplication;
import org.commcare.models.database.SqlStorage;
import org.commcare.android.database.user.models.FormRecord;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Vector;
/**
* Simple utility/helper methods for common operations across
* the application
*
* @author ctsims
*/
public class StorageUtils {
@NonNull
public static Vector<Integer> getUnsentOrUnprocessedFormIdsForCurrentApp(
SqlStorage<FormRecord> storage) {
String currentAppId =
CommCareApplication.instance().getCurrentApp().getAppRecord().getApplicationId();
Vector<Integer> ids = storage.getIDsForValues(
new String[]{FormRecord.META_STATUS, FormRecord.META_APP_ID},
new Object[]{FormRecord.STATUS_UNSENT, currentAppId});
ids.addAll(storage.getIDsForValues(
new String[]{FormRecord.META_STATUS, FormRecord.META_APP_ID},
new Object[]{FormRecord.STATUS_COMPLETE, currentAppId}));
return ids;
}
public static Vector<FormRecord> getUnsentOrUnprocessedFormRecordsForCurrentApp(
SqlStorage<FormRecord> storage) {
String currentAppId =
CommCareApplication.instance().getCurrentApp().getAppRecord().getApplicationId();
Vector<FormRecord> records = storage.getRecordsForValues(
new String[]{FormRecord.META_STATUS, FormRecord.META_APP_ID},
new Object[]{FormRecord.STATUS_UNSENT, currentAppId});
records.addAll(storage.getRecordsForValues(
new String[]{FormRecord.META_STATUS, FormRecord.META_APP_ID},
new Object[]{FormRecord.STATUS_COMPLETE, currentAppId}));
return records;
}
public static int getNumIncompleteForms() {
return getNumFormsWithStatus(FormRecord.STATUS_INCOMPLETE);
}
public static int getNumQuarantinedForms() {
return getNumFormsWithStatus(FormRecord.STATUS_LIMBO);
}
public static int getNumUnsentForms() {
return getNumFormsWithStatus(FormRecord.STATUS_UNSENT);
}
private static int getNumFormsWithStatus(String status) {
SqlStorage<FormRecord> formsStorage =
CommCareApplication.instance().getUserStorage(FormRecord.class);
String currentAppId =
CommCareApplication.instance().getCurrentApp().getAppRecord().getApplicationId();
return formsStorage.getIDsForValues(
new String[]{FormRecord.META_STATUS, FormRecord.META_APP_ID},
new String[]{status, currentAppId}).size();
}
public static FormRecord[] getUnsentRecordsForCurrentApp(SqlStorage<FormRecord> storage) {
// TODO: This could all be one big sql query instead of doing it in code
Vector<FormRecord> records;
try {
records = getUnsentOrUnprocessedFormRecordsForCurrentApp(storage);
} catch (SessionUnavailableException e) {
records = new Vector<>();
}
if (records.size() == 0) {
return new FormRecord[0];
}
// Order ids so they're submitted to and processed by the server in the correct order.
sortRecordsBySubmissionOrderingNumber(records);
FormRecord[] recordArray = new FormRecord[records.size()];
for (int i = 0; i < records.size(); ++i) {
recordArray[i] = records.get(i);
}
return recordArray;
}
private static void sortRecordsBySubmissionOrderingNumber(Vector<FormRecord> records) {
Collections.sort(records, new Comparator<FormRecord>() {
@Override
public int compare(FormRecord form1, FormRecord form2) {
int form1OrderingNum = form1.getSubmissionOrderingNumber();
int form2OrderingNum = form2.getSubmissionOrderingNumber();
if (form1OrderingNum < form2OrderingNum) {
return -1;
}
if (form1OrderingNum > form2OrderingNum) {
return 1;
}
return 0;
}
});
}
public static int getNextFormSubmissionNumber() {
SqlStorage<FormRecord> storage =
CommCareApplication.instance().getUserStorage(FormRecord.class);
Vector<FormRecord> records =
StorageUtils.getUnsentOrUnprocessedFormRecordsForCurrentApp(storage);
int maxSubmissionNumber = -1;
for (FormRecord record : records) {
if (record.getSubmissionOrderingNumber() > maxSubmissionNumber) {
maxSubmissionNumber = record.getSubmissionOrderingNumber();
}
}
return maxSubmissionNumber + 1;
}
}