Example usage for android.content ContentValues keySet

List of usage examples for android.content ContentValues keySet

Introduction

In this page you can find the example usage for android.content ContentValues keySet.

Prototype

public Set<String> keySet() 

Source Link

Document

Returns a set of all of the keys

Usage

From source file:org.opendatakit.services.database.utlities.ODKDatabaseImplUtils.java

/**
 * Resolve the server conflict by taking the local changes plus a value map
 * of select server field values.  This map should not update any metadata
 * fields -- it should just contain user data fields.
 * <p/>// w  ww .j a  v  a  2  s.c o  m
 * It is an error to call this if the local change is to delete the row.
 *
 * @param db
 * @param tableId
 * @param cvValues   key-value pairs from the server record that we should incorporate.
 * @param rowId
 * @param activeUser
 * @param rolesList
 * @param locale
 */
public void resolveServerConflictTakeLocalRowPlusServerDeltasWithId(OdkConnectionInterface db, String tableId,
        ContentValues cvValues, String rowId, String activeUser, String rolesList, String locale)
        throws ActionNotAuthorizedException {

    // TODO: if rolesList does not contain RoleConsts.ROLE_SUPER_USER or RoleConsts.ROLE_ADMINISTRATOR
    // TODO: then take the server's rowFilterScope rather than the user's values of those.
    // TODO: and apply the update only if the user roles support that update.

    // I.e., if the user is super-user or higher, we should take local FilterScope.
    // otherwise, we should take server FilterScope. Or should we allow user to select
    // which to take?

    boolean inTransaction = false;
    try {

        inTransaction = db.inTransaction();
        if (!inTransaction) {
            db.beginTransactionNonExclusive();
        }

        OrderedColumns orderedColumns = getUserDefinedColumns(db, tableId);

        AccessContext accessContext = getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST);

        // get both conflict records for this row.
        // the local record is always before the server record (due to conflict_type values)
        BaseTable table = privilegedQuery(db, tableId,
                QueryUtil.buildSqlStatement(tableId,
                        K_DATATABLE_ID_EQUALS_PARAM + S_AND + DataTableColumns.CONFLICT_TYPE + S_IS_NOT_NULL,
                        null, null, new String[] { DataTableColumns.CONFLICT_TYPE }, new String[] { "ASC" }),
                new Object[] { rowId }, null, accessContext);

        if (table.getNumberOfRows() != 2) {
            throw new IllegalStateException(
                    "Did not find a server and local row when resolving conflicts for rowId: " + rowId);
        }
        Row localRow = table.getRowAtIndex(0);
        Row serverRow = table.getRowAtIndex(1);

        int localConflictType = Integer.parseInt(localRow.getDataByKey(DataTableColumns.CONFLICT_TYPE));

        int serverConflictType = Integer.parseInt(serverRow.getDataByKey(DataTableColumns.CONFLICT_TYPE));

        if (localConflictType != ConflictType.LOCAL_UPDATED_UPDATED_VALUES
                && localConflictType != ConflictType.LOCAL_DELETED_OLD_VALUES) {
            throw new IllegalStateException(
                    "Did not find local conflict row when resolving conflicts for rowId: " + rowId);
        }

        if (serverConflictType != ConflictType.SERVER_UPDATED_UPDATED_VALUES
                && serverConflictType != ConflictType.SERVER_DELETED_OLD_VALUES) {
            throw new IllegalStateException(
                    "Did not find server conflict row when resolving conflicts for rowId: " + rowId);
        }

        if (localConflictType == ConflictType.LOCAL_DELETED_OLD_VALUES) {
            throw new IllegalStateException(
                    "Local row is marked for deletion -- blending does not make sense for rowId: " + rowId);
        }

        HashMap<String, Object> updateValues = new HashMap<String, Object>();
        for (String key : cvValues.keySet()) {
            updateValues.put(key, cvValues.get(key));
        }

        // clean up the incoming map of server values to retain
        cleanUpValuesMap(orderedColumns, updateValues);
        updateValues.put(DataTableColumns.ID, rowId);
        updateValues.put(DataTableColumns.ROW_ETAG, serverRow.getDataByKey(DataTableColumns.ROW_ETAG));

        // update what was the local conflict record with the local's changes
        // by the time we apply the update, the local conflict record will be
        // restored to the proper (conflict_type, sync_state) values.
        //
        // No need to specify them here.

        // but take the local's metadata values (i.e., do not change these
        // during the update) ...
        updateValues.put(DataTableColumns.FORM_ID, localRow.getDataByKey(DataTableColumns.FORM_ID));
        updateValues.put(DataTableColumns.LOCALE, localRow.getDataByKey(DataTableColumns.LOCALE));
        updateValues.put(DataTableColumns.SAVEPOINT_TYPE,
                localRow.getDataByKey(DataTableColumns.SAVEPOINT_TYPE));
        updateValues.put(DataTableColumns.SAVEPOINT_TIMESTAMP,
                localRow.getDataByKey(DataTableColumns.SAVEPOINT_TIMESTAMP));
        updateValues.put(DataTableColumns.SAVEPOINT_CREATOR,
                localRow.getDataByKey(DataTableColumns.SAVEPOINT_CREATOR));

        // take the server's filter metadata values ...
        TreeMap<String, Object> privilegedUpdateValues = new TreeMap<String, Object>();
        privilegedUpdateValues.put(DataTableColumns.ID, rowId);
        privilegedUpdateValues.put(DataTableColumns.FILTER_TYPE,
                serverRow.getDataByKey(DataTableColumns.FILTER_TYPE));
        privilegedUpdateValues.put(DataTableColumns.FILTER_VALUE,
                serverRow.getDataByKey(DataTableColumns.FILTER_VALUE));
        privilegedUpdateValues.put(DataTableColumns.SAVEPOINT_TIMESTAMP,
                serverRow.getDataByKey(DataTableColumns.SAVEPOINT_TIMESTAMP));
        privilegedUpdateValues.put(DataTableColumns.SAVEPOINT_CREATOR,
                serverRow.getDataByKey(DataTableColumns.SAVEPOINT_CREATOR));

        // delete the record of the server row
        deleteServerConflictRowWithId(db, tableId, rowId);

        // move the local conflict back into the normal (null) state

        restoreRowFromConflict(db, tableId, rowId, SyncState.changed, localConflictType);

        // update local with server's changes
        updateRowWithId(db, tableId, orderedColumns, updateValues, activeUser, rolesList, locale);

        // update as if user has admin privileges.
        // do this so we can update the filter type and filter value
        updateRowWithId(db, tableId, orderedColumns, privilegedUpdateValues, activeUser,
                RoleConsts.ADMIN_ROLES_LIST, locale);

        if (!inTransaction) {
            db.setTransactionSuccessful();
        }
    } finally {
        if (db != null) {
            if (!inTransaction) {
                db.endTransaction();
            }
        }
    }
}

From source file:org.opendatakit.services.database.utilities.ODKDatabaseImplUtils.java

/**
 * Resolve the server conflict by taking the local changes plus a value map
 * of select server field values.  This map should not update any metadata
 * fields -- it should just contain user data fields.
 * <p/>/*from w  ww .j  a  v  a  2  s.  c om*/
 * It is an error to call this if the local change is to delete the row.
 *
 * @param db
 * @param tableId
 * @param cvValues   key-value pairs from the server record that we should incorporate.
 * @param rowId
 * @param activeUser
 * @param rolesList
 * @param locale
 */
public void resolveServerConflictTakeLocalRowPlusServerDeltasWithId(OdkConnectionInterface db, String tableId,
        ContentValues cvValues, String rowId, String activeUser, String rolesList, String locale)
        throws ActionNotAuthorizedException {

    // TODO: if rolesList does not contain RoleConsts.ROLE_SUPER_USER or RoleConsts.ROLE_ADMINISTRATOR
    // TODO: then take the server's rowFilterScope rather than the user's values of those.
    // TODO: and apply the update only if the user roles support that update.

    // I.e., if the user is super-user or higher, we should take local FilterScope.
    // otherwise, we should take server FilterScope. Or should we allow user to select
    // which to take?

    boolean inTransaction = false;
    try {

        inTransaction = db.inTransaction();
        if (!inTransaction) {
            db.beginTransactionNonExclusive();
        }

        OrderedColumns orderedColumns = getUserDefinedColumns(db, tableId);

        AccessContext accessContext = getAccessContext(db, tableId, activeUser, RoleConsts.ADMIN_ROLES_LIST);

        // get both conflict records for this row.
        // the local record is always before the server record (due to conflict_type values)
        BaseTable table = privilegedQuery(db, tableId,
                QueryUtil.buildSqlStatement(tableId,
                        K_DATATABLE_ID_EQUALS_PARAM + S_AND + DataTableColumns.CONFLICT_TYPE + S_IS_NOT_NULL,
                        null, null, new String[] { DataTableColumns.CONFLICT_TYPE }, new String[] { "ASC" }),
                new Object[] { rowId }, null, accessContext);

        if (table.getNumberOfRows() != 2) {
            throw new IllegalStateException(
                    "Did not find a server and local row when resolving conflicts for rowId: " + rowId);
        }
        Row localRow = table.getRowAtIndex(0);
        Row serverRow = table.getRowAtIndex(1);

        int localConflictType = Integer.parseInt(localRow.getDataByKey(DataTableColumns.CONFLICT_TYPE));

        int serverConflictType = Integer.parseInt(serverRow.getDataByKey(DataTableColumns.CONFLICT_TYPE));

        if (localConflictType != ConflictType.LOCAL_UPDATED_UPDATED_VALUES
                && localConflictType != ConflictType.LOCAL_DELETED_OLD_VALUES) {
            throw new IllegalStateException(
                    "Did not find local conflict row when resolving conflicts for rowId: " + rowId);
        }

        if (serverConflictType != ConflictType.SERVER_UPDATED_UPDATED_VALUES
                && serverConflictType != ConflictType.SERVER_DELETED_OLD_VALUES) {
            throw new IllegalStateException(
                    "Did not find server conflict row when resolving conflicts for rowId: " + rowId);
        }

        if (localConflictType == ConflictType.LOCAL_DELETED_OLD_VALUES) {
            throw new IllegalStateException(
                    "Local row is marked for deletion -- blending does not make sense for rowId: " + rowId);
        }

        HashMap<String, Object> updateValues = new HashMap<String, Object>();
        for (String key : cvValues.keySet()) {
            updateValues.put(key, cvValues.get(key));
        }

        // clean up the incoming map of server values to retain
        cleanUpValuesMap(orderedColumns, updateValues);
        updateValues.put(DataTableColumns.ID, rowId);
        updateValues.put(DataTableColumns.ROW_ETAG, serverRow.getDataByKey(DataTableColumns.ROW_ETAG));

        // update what was the local conflict record with the local's changes
        // by the time we apply the update, the local conflict record will be
        // restored to the proper (conflict_type, sync_state) values.
        //
        // No need to specify them here.

        // but take the local's metadata values (i.e., do not change these
        // during the update) ...
        updateValues.put(DataTableColumns.FORM_ID, localRow.getDataByKey(DataTableColumns.FORM_ID));
        updateValues.put(DataTableColumns.LOCALE, localRow.getDataByKey(DataTableColumns.LOCALE));
        updateValues.put(DataTableColumns.SAVEPOINT_TYPE,
                localRow.getDataByKey(DataTableColumns.SAVEPOINT_TYPE));
        updateValues.put(DataTableColumns.SAVEPOINT_TIMESTAMP,
                localRow.getDataByKey(DataTableColumns.SAVEPOINT_TIMESTAMP));
        updateValues.put(DataTableColumns.SAVEPOINT_CREATOR,
                localRow.getDataByKey(DataTableColumns.SAVEPOINT_CREATOR));

        // take the server's filter metadata values ...
        TreeMap<String, Object> privilegedUpdateValues = new TreeMap<String, Object>();
        privilegedUpdateValues.put(DataTableColumns.ID, rowId);
        privilegedUpdateValues.put(DataTableColumns.DEFAULT_ACCESS,
                serverRow.getDataByKey(DataTableColumns.DEFAULT_ACCESS));
        privilegedUpdateValues.put(DataTableColumns.ROW_OWNER,
                serverRow.getDataByKey(DataTableColumns.ROW_OWNER));
        privilegedUpdateValues.put(DataTableColumns.GROUP_READ_ONLY,
                serverRow.getDataByKey(DataTableColumns.GROUP_READ_ONLY));
        privilegedUpdateValues.put(DataTableColumns.GROUP_MODIFY,
                serverRow.getDataByKey(DataTableColumns.GROUP_MODIFY));
        privilegedUpdateValues.put(DataTableColumns.GROUP_PRIVILEGED,
                serverRow.getDataByKey(DataTableColumns.GROUP_PRIVILEGED));
        privilegedUpdateValues.put(DataTableColumns.SAVEPOINT_TIMESTAMP,
                serverRow.getDataByKey(DataTableColumns.SAVEPOINT_TIMESTAMP));
        privilegedUpdateValues.put(DataTableColumns.SAVEPOINT_CREATOR,
                serverRow.getDataByKey(DataTableColumns.SAVEPOINT_CREATOR));

        // delete the record of the server row
        deleteServerConflictRowWithId(db, tableId, rowId);

        // move the local conflict back into the normal (null) state

        restoreRowFromConflict(db, tableId, rowId, SyncState.changed, localConflictType);

        // update local with server's changes
        updateRowWithId(db, tableId, orderedColumns, updateValues, activeUser, rolesList, locale);

        // update as if user has admin privileges.
        // do this so we can update the filter type and filter value
        updateRowWithId(db, tableId, orderedColumns, privilegedUpdateValues, activeUser,
                RoleConsts.ADMIN_ROLES_LIST, locale);

        if (!inTransaction) {
            db.setTransactionSuccessful();
        }
    } finally {
        if (db != null) {
            if (!inTransaction) {
                db.endTransaction();
            }
        }
    }
}