List of usage examples for android.content ContentValues keySet
public Set<String> keySet()
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(); } } } }