Search in sources :

Example 6 with ModelField

use of com.amplifyframework.core.model.ModelField in project amplify-android by aws-amplify.

the class SQLiteTable method fromSchema.

/**
 * Static method to convert an instance of {@link ModelSchema}
 * into a SQLite table representation. This representation will
 * be useful for storage engine when interacting with SQLite database.
 *
 * Instances of {@link ModelField} inside the schema will be converted
 * to {@link SQLiteColumn} if they meet the following conditions:
 *
 *      1) field is NOT a associated with another model OR,
 *      2) field is the foreign key of relationship
 *
 * The generated SQLite column will encapsulate additional information
 * that is not contained inside {@link ModelField}, such as
 *
 *      1) which table (model) does this field belong to?,
 *      2) what is the corresponding SQLite data type for field type,
 *      3) whether the field represents a foreign key, AND
 *      4) IF it is a foreign key, then which model does it it identify?
 *
 * @param modelSchema An instance of {@link ModelSchema}
 * @return Adapted SQLite table
 */
@NonNull
public static SQLiteTable fromSchema(@NonNull ModelSchema modelSchema) {
    Objects.requireNonNull(modelSchema);
    Map<String, ModelAssociation> associations = modelSchema.getAssociations();
    Map<String, SQLiteColumn> sqlColumns = new TreeMap<>();
    for (ModelField modelField : modelSchema.getFields().values()) {
        final ModelAssociation association = associations.get(modelField.getName());
        final boolean isAssociated = association != null;
        // and is NOT the foreign key
        if (isAssociated && !association.isOwner()) {
            continue;
        }
        // All associated fields are also foreign keys at this point
        SQLiteColumn column = SQLiteColumn.builder().name(isAssociated ? association.getTargetName() : modelField.getName()).fieldName(modelField.getName()).tableName(modelSchema.getName()).ownerOf(isAssociated ? association.getAssociatedType() : null).isNonNull(modelField.isRequired()).dataType(sqlTypeFromModelField(modelField)).build();
        sqlColumns.put(modelField.getName(), column);
    }
    return SQLiteTable.builder().name(modelSchema.getName()).columns(sqlColumns).build();
}
Also used : ModelAssociation(com.amplifyframework.core.model.ModelAssociation) ModelField(com.amplifyframework.core.model.ModelField) TreeMap(java.util.TreeMap) NonNull(androidx.annotation.NonNull)

Example 7 with ModelField

use of com.amplifyframework.core.model.ModelField in project amplify-android by aws-amplify.

the class AppSyncRequestFactory method extractFieldValue.

private static Object extractFieldValue(String fieldName, Model instance, ModelSchema schema) throws AmplifyException {
    if (instance instanceof SerializedModel) {
        SerializedModel serializedModel = (SerializedModel) instance;
        Map<String, Object> serializedData = serializedModel.getSerializedData();
        ModelField field = schema.getFields().get(fieldName);
        Object fieldValue = serializedData.get(fieldName);
        if (fieldValue != null && field != null && field.isCustomType()) {
            return extractCustomTypeFieldValue(fieldName, serializedData.get(fieldName));
        }
        return fieldValue;
    }
    try {
        Field privateField = instance.getClass().getDeclaredField(fieldName);
        privateField.setAccessible(true);
        return privateField.get(instance);
    } catch (Exception exception) {
        throw new AmplifyException("An invalid field was provided. " + fieldName + " is not present in " + schema.getName(), exception, "Check if this model schema is a correct representation of the fields in the provided Object");
    }
}
Also used : ModelField(com.amplifyframework.core.model.ModelField) Field(java.lang.reflect.Field) AmplifyException(com.amplifyframework.AmplifyException) ModelField(com.amplifyframework.core.model.ModelField) SerializedModel(com.amplifyframework.core.model.SerializedModel) AmplifyException(com.amplifyframework.AmplifyException) DataStoreException(com.amplifyframework.datastore.DataStoreException)

Example 8 with ModelField

use of com.amplifyframework.core.model.ModelField in project amplify-android by aws-amplify.

the class PendingMutationPersistentRecordTest method modelSchemaGenerationSucceeds.

/**
 * Generation of a {@link ModelSchema} for the {@link PendingMutation.PersistentRecord}
 * succeeds.
 * @throws AmplifyException from Amplify configuration
 */
@Test
public void modelSchemaGenerationSucceeds() throws AmplifyException {
    List<ModelField> fields = Arrays.asList(ModelField.builder().name("id").targetType("ID").isRequired(true).javaClassForValue(String.class).build(), ModelField.builder().name("containedModelId").targetType("String").isRequired(true).javaClassForValue(String.class).build(), ModelField.builder().name("serializedMutationData").targetType("String").isRequired(true).javaClassForValue(String.class).build(), ModelField.builder().name("containedModelClassName").targetType("String").isRequired(true).javaClassForValue(String.class).build());
    Map<String, ModelField> expectedFieldsMap = new HashMap<>();
    for (ModelField field : fields) {
        expectedFieldsMap.put(field.getName(), field);
    }
    final ModelIndex index = ModelIndex.builder().indexFieldNames(Collections.singletonList("containedModelClassName")).indexName("containedModelClassNameBasedIndex").build();
    assertEquals(// Expected
    ModelSchema.builder().name("PersistentRecord").pluralName("PersistentRecords").fields(expectedFieldsMap).indexes(Collections.singletonMap("containedModelClassNameBasedIndex", index)).modelClass(PendingMutation.PersistentRecord.class).build(), // Actual
    ModelSchema.fromModelClass(PendingMutation.PersistentRecord.class));
}
Also used : ModelField(com.amplifyframework.core.model.ModelField) HashMap(java.util.HashMap) ModelIndex(com.amplifyframework.core.model.ModelIndex) PendingMutation(com.amplifyframework.datastore.syncengine.PendingMutation) Test(org.junit.Test)

Example 9 with ModelField

use of com.amplifyframework.core.model.ModelField in project amplify-android by aws-amplify.

the class AppSyncRequestFactory method extractFieldLevelData.

private static Map<String, Object> extractFieldLevelData(ModelSchema schema, Model instance) throws AmplifyException {
    final Map<String, Object> result = new HashMap<>();
    for (ModelField modelField : schema.getFields().values()) {
        if (modelField.isReadOnly()) {
            // Skip read only fields, since they should not be included on the input object.
            continue;
        }
        String fieldName = modelField.getName();
        final ModelAssociation association = schema.getAssociations().get(fieldName);
        if (instance instanceof SerializedModel && !((SerializedModel) instance).getSerializedData().containsKey(fieldName)) {
            // Skip fields that are not set, so that they are not set to null in the request.
            continue;
        }
        if (association == null) {
            result.put(fieldName, extractFieldValue(modelField.getName(), instance, schema));
        } else if (association.isOwner()) {
            String targetName = association.getTargetName();
            result.put(targetName, extractAssociateId(modelField, instance, schema));
        }
    // Ignore if field is associated, but is not a "belongsTo" relationship
    }
    return result;
}
Also used : ModelAssociation(com.amplifyframework.core.model.ModelAssociation) ModelField(com.amplifyframework.core.model.ModelField) HashMap(java.util.HashMap) SerializedModel(com.amplifyframework.core.model.SerializedModel)

Example 10 with ModelField

use of com.amplifyframework.core.model.ModelField in project amplify-android by aws-amplify.

the class ModelHelper method getValue.

/**
 * Uses reflection to get a property value on a <code>Model</code> by its <code>ModelField</code>
 * reference. This method prioritizes the property getter and fallback to the field itself
 * if a getter doesn't exist.
 *
 * @param model the model instance
 * @param field the model field
 * @param <M> the model concrete type
 * @return the field value or <code>null</code>
 * @throws DataStoreException in case of a error happens during the dynamic reflection calls
 */
public static <M extends Model> Object getValue(M model, ModelField field) throws DataStoreException {
    final Class<? extends Model> modelClass = model.getClass();
    final String fieldName = field.getName();
    final String getterName = "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
    try {
        final Method fieldGetter = modelClass.getMethod(getterName);
        return fieldGetter.invoke(model);
    } catch (Exception exception) {
        LOGGER.verbose(String.format("Could not find %s() on %s. Fallback to direct field access.", getterName, modelClass.getName()));
    }
    // fallback to direct field access
    try {
        final Field fieldReference = modelClass.getDeclaredField(fieldName);
        fieldReference.setAccessible(true);
        return fieldReference.get(model);
    } catch (Exception fallbackException) {
        throw new DataStoreException("Error when reading the property " + fieldName + " from class " + modelClass.getName(), fallbackException, AmplifyException.REPORT_BUG_TO_AWS_SUGGESTION);
    }
}
Also used : Field(java.lang.reflect.Field) ModelField(com.amplifyframework.core.model.ModelField) DataStoreException(com.amplifyframework.datastore.DataStoreException) Method(java.lang.reflect.Method) DataStoreException(com.amplifyframework.datastore.DataStoreException) AmplifyException(com.amplifyframework.AmplifyException)

Aggregations

ModelField (com.amplifyframework.core.model.ModelField)14 HashMap (java.util.HashMap)9 ModelSchema (com.amplifyframework.core.model.ModelSchema)8 SerializedModel (com.amplifyframework.core.model.SerializedModel)7 ModelAssociation (com.amplifyframework.core.model.ModelAssociation)5 SchemaRegistry (com.amplifyframework.core.model.SchemaRegistry)4 Test (org.junit.Test)4 AmplifyException (com.amplifyframework.AmplifyException)3 CustomTypeSchema (com.amplifyframework.core.model.CustomTypeSchema)3 ArrayList (java.util.ArrayList)3 NonNull (androidx.annotation.NonNull)2 AuthRule (com.amplifyframework.core.model.AuthRule)2 CustomTypeField (com.amplifyframework.core.model.CustomTypeField)2 DataStoreException (com.amplifyframework.datastore.DataStoreException)2 Field (java.lang.reflect.Field)2 List (java.util.List)2 Map (java.util.Map)2 Consumer (com.amplifyframework.core.Consumer)1 Model (com.amplifyframework.core.model.Model)1 ModelIndex (com.amplifyframework.core.model.ModelIndex)1