diff --git a/survey_app/src/main/java/org/opendatakit/survey/utilities/FormInfo.java b/survey_app/src/main/java/org/opendatakit/survey/utilities/FormInfo.java index 99969c41..147afefd 100644 --- a/survey_app/src/main/java/org/opendatakit/survey/utilities/FormInfo.java +++ b/survey_app/src/main/java/org/opendatakit/survey/utilities/FormInfo.java @@ -9,13 +9,15 @@ public final class FormInfo { public final String formVersion; public final String formDisplayName; public final String formDisplaySubtext; + public final int formIncompleteEntriesCount; FormInfo(String tableId, String formId, String formVersion, String formDisplayName, String - formDisplaySubtext) { + formDisplaySubtext , int formIncompleteEntriesCount) { this.tableId = tableId; this.formId = formId; this.formVersion = formVersion; this.formDisplayName = formDisplayName; this.formDisplaySubtext = formDisplaySubtext; + this.formIncompleteEntriesCount = formIncompleteEntriesCount; } } diff --git a/survey_app/src/main/java/org/opendatakit/survey/utilities/FormListLoader.java b/survey_app/src/main/java/org/opendatakit/survey/utilities/FormListLoader.java index afb7d086..bf61de4d 100644 --- a/survey_app/src/main/java/org/opendatakit/survey/utilities/FormListLoader.java +++ b/survey_app/src/main/java/org/opendatakit/survey/utilities/FormListLoader.java @@ -18,11 +18,20 @@ import android.content.Context; import android.database.Cursor; import android.net.Uri; + +import org.opendatakit.application.CommonApplication; +import org.opendatakit.database.data.OrderedColumns; +import org.opendatakit.database.data.UserTable; +import org.opendatakit.database.service.DbHandle; +import org.opendatakit.database.service.UserDbInterface; +import org.opendatakit.database.utilities.QueryUtil; +import org.opendatakit.exception.ServicesAvailabilityException; import org.opendatakit.properties.CommonToolProperties; import org.opendatakit.properties.PropertiesSingleton; import org.opendatakit.provider.FormsColumns; import org.opendatakit.provider.FormsProviderAPI; import org.opendatakit.survey.R; +import org.opendatakit.survey.application.Survey; import org.opendatakit.utilities.LocalizationUtils; import java.text.SimpleDateFormat; @@ -65,7 +74,7 @@ public FormListLoader(Context context, String appName) { int idxFormTitle = c.getColumnIndex(FormsColumns.DISPLAY_NAME); int idxLastUpdateDate = c.getColumnIndex(FormsColumns.DATE); int idxFormVersion = c.getColumnIndex(FormsColumns.FORM_VERSION); - + UserDbInterface dbInterface =Survey.getInstance().getDatabase(); SimpleDateFormat formatter = new SimpleDateFormat(getContext().getString(R.string .last_updated_on_date_at_time), Locale.getDefault()); @@ -77,6 +86,9 @@ public FormListLoader(Context context, String appName) { Date lastModificationDate = new Date(timestamp); String formTitle = c.getString(idxFormTitle); + OrderedColumns columnDefinitions = getColumnDefinitions(appName, tableId); + int tableIncompleteCount = loadInfoAboutForms(tableId , dbInterface , columnDefinitions); + FormInfo info = new FormInfo( tableId, c.getString(idxFormId), @@ -84,7 +96,8 @@ public FormListLoader(Context context, String appName) { LocalizationUtils.getLocalizedDisplayName(appName, tableId, props.getUserSelectedDefaultLocale(), formTitle), - formatter.format(lastModificationDate)); + formatter.format(lastModificationDate) , + tableIncompleteCount ); forms.add(info); } while ( c.moveToNext()); } @@ -125,4 +138,68 @@ public FormListLoader(Context context, String appName) { super.onStartLoading(); forceLoad(); } + + + public synchronized OrderedColumns getColumnDefinitions(String appName, String tableId) { + + OrderedColumns mColumnDefinitions = null; + CommonApplication app = Survey.getInstance(); + if (app.getDatabase() != null) + { + DbHandle db = null; + try + { + db = app.getDatabase().openDatabase( appName ); + mColumnDefinitions = app.getDatabase() + .getUserDefinedColumns( appName , db, tableId); + } catch (ServicesAvailabilityException e) + { + + throw new IllegalStateException("database went down -- handle this! " + e); + } finally + { + if (db != null) { + try + { + app.getDatabase().closeDatabase(appName, db); + } catch (ServicesAvailabilityException e) + { + + } + } + } + } + return mColumnDefinitions; + } + + private int loadInfoAboutForms(String iTableId , UserDbInterface dbInterface , OrderedColumns columnDefs) + { + DbHandle db = null; + String[] emptyArray = {}; + int countOfIncompleteRows = 0; + try { + db = dbInterface.openDatabase(appName); + SQLQueryStruct sqlQueryStruct = new SQLQueryStruct("_savepoint_type = 'INCOMPLETE' ", null, new String[]{}, + "", "", ""); + UserTable userTable = dbInterface.simpleQuery(appName, db, iTableId, columnDefs, + sqlQueryStruct.whereClause, sqlQueryStruct.selectionArgs, + sqlQueryStruct.groupBy == null ? emptyArray : sqlQueryStruct.groupBy, + sqlQueryStruct.having, + QueryUtil.convertStringToArray(sqlQueryStruct.orderByElementKey), + QueryUtil.convertStringToArray(sqlQueryStruct.orderByDirection), + null, null); + countOfIncompleteRows = userTable.getNumberOfRows(); + } + catch(ServicesAvailabilityException sae) { + throw new IllegalStateException("Database open -- while fetching incomplete stats count! " + sae); + } + finally { + try { + if (db != null) + dbInterface.closeDatabase(appName, db); + } + catch (ServicesAvailabilityException sae) {} + } + return countOfIncompleteRows; + } } diff --git a/survey_app/src/main/java/org/opendatakit/survey/utilities/SQLQueryStruct.java b/survey_app/src/main/java/org/opendatakit/survey/utilities/SQLQueryStruct.java new file mode 100644 index 00000000..389bfd6b --- /dev/null +++ b/survey_app/src/main/java/org/opendatakit/survey/utilities/SQLQueryStruct.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2014 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package org.opendatakit.survey.utilities; + +import org.opendatakit.database.queries.BindArgs; + +/** + * Basic holder for the components of a SQL query. + * + * @author sudar.sam@gmail.com + */ +public class SQLQueryStruct { + + /** + * A sql clause that narrows down the list of returned rows + */ + public String whereClause; + /** + * TODO + */ + public BindArgs selectionArgs; + /** + * A list of columns to group by + */ + public String[] groupBy; + /** + * A SQL having clause + */ + public String having; + /** + * The column id of the column to sort the results by + */ + public String orderByElementKey; + /** + * the direction to sort by, ASC for ascending, DESC for descending + */ + public String orderByDirection; + + /** + * A simple constructor that stores its properties + * + * @param whereClause A sql clause that narrows down the list of returned rows + * @param selectionArgs TODO + * @param groupBy A list of columns to group by + * @param having A SQL having clause + * @param orderByElementKey The column id of the column to sort the results by + * @param orderByDirection the direction to sort by, ASC for ascending, DESC for descending + */ + public SQLQueryStruct(String whereClause, BindArgs selectionArgs, String[] groupBy, String having, + String orderByElementKey, String orderByDirection) { + this.whereClause = whereClause; + this.selectionArgs = selectionArgs; + this.groupBy = groupBy; + this.having = having; + this.orderByElementKey = orderByElementKey; + this.orderByDirection = orderByDirection; + } + +}