use of com.amplifyframework.core.model.ModelSchema in project amplify-android by aws-amplify.
the class CompoundModelProvider method of.
/**
* Gets an {@link CompoundModelProvider} that provides all of the same models as the
* constituent {@link ModelProvider} that are provided. The version of the returned
* {@link CompoundModelProvider} shall be stable UUID hash of the versions of all
* provided {@link ModelProvider}s.
* @param modelProviders model providers
* @return A compound provider, which provides the models of all of the input providers
*/
@NonNull
public static CompoundModelProvider of(@NonNull ModelProvider... modelProviders) {
final Map<String, ModelSchema> modelSchemaMap = new HashMap<>();
final Map<String, CustomTypeSchema> customTypeSchemaMap = new HashMap<>();
StringBuilder componentVersionBuffer = new StringBuilder();
for (ModelProvider componentProvider : modelProviders) {
componentVersionBuffer.append(componentProvider.version());
modelSchemaMap.putAll(componentProvider.modelSchemas());
customTypeSchemaMap.putAll(componentProvider.customTypeSchemas());
}
String version = UUID.nameUUIDFromBytes(componentVersionBuffer.toString().getBytes()).toString();
SimpleModelProvider delegateProvider = SimpleModelProvider.instance(version, modelSchemaMap, customTypeSchemaMap);
return new CompoundModelProvider(delegateProvider);
}
use of com.amplifyframework.core.model.ModelSchema in project amplify-android by aws-amplify.
the class SQLiteCommandFactory method recursivelyBuildJoins.
/**
* Recursively build joins for multilevel nested joins.
*/
private void recursivelyBuildJoins(SQLiteTable table, Map<String, List<SQLiteColumn>> columns, StringBuilder joinStatement, Map<String, Integer> tableCount, String tableAlias) {
// Joins the foreign keys
// LEFT JOIN if foreign key is optional, INNER JOIN otherwise.
final Iterator<SQLiteColumn> foreignKeyIterator = table.getForeignKeys().iterator();
while (foreignKeyIterator.hasNext()) {
final SQLiteColumn foreignKey = foreignKeyIterator.next();
final String ownedTableName = foreignKey.getOwnedType();
final ModelSchema ownedSchema = schemaRegistry.getModelSchemaForModelClass(ownedTableName);
final SQLiteTable ownedTable = SQLiteTable.fromSchema(ownedSchema);
int newOwnedTableCount = 1;
String ownedTableAlias = ownedTableName;
if (tableCount.containsKey(ownedTableName)) {
Integer currentOwnedTableCount = tableCount.get(ownedTableName);
newOwnedTableCount += currentOwnedTableCount == null ? 0 : currentOwnedTableCount;
ownedTableAlias += newOwnedTableCount;
}
tableCount.put(ownedTableName, newOwnedTableCount);
columns.put(ownedTableAlias, ownedTable.getSortedColumns());
SqlKeyword joinType = foreignKey.isNonNull() ? SqlKeyword.INNER_JOIN : SqlKeyword.LEFT_JOIN;
joinStatement.append(joinType).append(SqlKeyword.DELIMITER).append(Wrap.inBackticks(ownedTableName)).append(SqlKeyword.DELIMITER);
if (!ownedTableName.equals(ownedTableAlias)) {
joinStatement.append(SqlKeyword.AS).append(SqlKeyword.DELIMITER).append(Wrap.inBackticks(ownedTableAlias)).append(SqlKeyword.DELIMITER);
}
// Reference the foreign key and primary key using the corresponding table's alias.
String foreignKeyName = foreignKey.getQuotedColumnName().replace(table.getName(), tableAlias);
String ownedTablePrimaryKeyName = ownedTable.getPrimaryKeyColumnName().replace(ownedTableName, ownedTableAlias);
joinStatement.append(SqlKeyword.ON).append(SqlKeyword.DELIMITER).append(foreignKeyName).append(SqlKeyword.EQUAL).append(ownedTablePrimaryKeyName);
if (foreignKeyIterator.hasNext()) {
joinStatement.append(SqlKeyword.DELIMITER);
}
// important that this comes last to maintain the order of the joins
recursivelyBuildJoins(ownedTable, columns, joinStatement, tableCount, ownedTableAlias);
}
}
use of com.amplifyframework.core.model.ModelSchema in project amplify-android by aws-amplify.
the class SQLiteModelFieldTypeConverter method convertModelAssociationToTarget.
private Object convertModelAssociationToTarget(@NonNull Cursor cursor, @NonNull ModelField field) throws DataStoreException {
// Eager load model if the necessary columns are present inside the cursor.
// At the time of implementation, cursor should have been joined with these
// columns IF AND ONLY IF the model is a foreign key to the inner model.
ModelSchema innerModelSchema = schemaRegistry.getModelSchemaForModelClass(field.getTargetType());
SQLiteModelFieldTypeConverter nestedModelConverter = new SQLiteModelFieldTypeConverter(innerModelSchema, schemaRegistry, gson, cursorInnerModelCounts);
return nestedModelConverter.buildMapForModel(cursor);
}
use of com.amplifyframework.core.model.ModelSchema in project amplify-android by aws-amplify.
the class SQLiteModelTree method recurseTree.
private void recurseTree(Map<ModelSchema, Set<String>> map, ModelSchema modelSchema, Collection<String> parentIds) {
for (ModelAssociation association : modelSchema.getAssociations().values()) {
switch(association.getName()) {
case "HasOne":
case "HasMany":
// model name
String childModel = association.getAssociatedType();
ModelSchema childSchema = registry.getModelSchemaForModelClass(childModel);
SQLiteTable childTable = SQLiteTable.fromSchema(childSchema);
String childId;
String parentId;
try {
childId = childTable.getPrimaryKey().getName();
parentId = // get a map of associations
childSchema.getAssociations().get(// get @BelongsTo association linked to this field
association.getAssociatedName()).getTargetName();
} catch (NullPointerException unexpectedAssociation) {
LOG.warn("Foreign key was not found due to unidirectional relationship without @BelongsTo. " + "Failed to publish cascading mutations.", unexpectedAssociation);
return;
}
// Collect every children one level deeper than current level
Set<String> childrenIds = new HashSet<>();
try (Cursor cursor = queryChildren(childTable.getName(), childId, parentId, parentIds)) {
if (cursor != null && cursor.moveToFirst()) {
int index = cursor.getColumnIndexOrThrow(childId);
do {
childrenIds.add(cursor.getString(index));
} while (cursor.moveToNext());
}
} catch (SQLiteException exception) {
// Don't cut the search short. Populate rest of the tree.
LOG.warn("Failed to query children of deleted model(s).", exception);
}
// Add queried result to the map
if (!childrenIds.isEmpty()) {
if (!map.containsKey(childSchema)) {
map.put(childSchema, childrenIds);
} else {
map.get(childSchema).addAll(childrenIds);
}
recurseTree(map, childSchema, childrenIds);
}
break;
case "BelongsTo":
default:
}
}
}
use of com.amplifyframework.core.model.ModelSchema in project amplify-android by aws-amplify.
the class SQLiteModelTree method descendantsOf.
/**
* Returns a map of descendants of a set of models (of same type).
* A model is a child of its parent if it uses its parent's ID as foreign key.
* @param root Collection of models to query its descendants of.
* @return List of models that are descendants of given models. These models will
* have the correct model type and ID, but no other field will be populated.
*/
<T extends Model> List<Model> descendantsOf(Collection<T> root) {
if (Empty.check(root)) {
return new ArrayList<>();
}
Map<ModelSchema, Set<String>> modelMap = new LinkedHashMap<>();
Model rootModel = root.iterator().next();
ModelSchema rootSchema = registry.getModelSchemaForModelClass(getModelName(rootModel));
Set<String> rootIds = new HashSet<>();
for (T model : root) {
rootIds.add(model.getId());
}
recurseTree(modelMap, rootSchema, rootIds);
List<Model> descendants = new ArrayList<>();
for (Map.Entry<ModelSchema, Set<String>> entry : modelMap.entrySet()) {
ModelSchema schema = entry.getKey();
for (String id : entry.getValue()) {
if (rootModel.getClass() == SerializedModel.class) {
SerializedModel dummyItem = SerializedModel.builder().serializedData(Collections.singletonMap("id", id)).modelSchema(schema).build();
descendants.add(dummyItem);
} else {
// Create dummy model instance using just the ID and model type
String dummyJson = gson.toJson(Collections.singletonMap("id", id));
Model dummyItem = gson.fromJson(dummyJson, schema.getModelClass());
descendants.add(dummyItem);
}
}
}
return descendants;
}
Aggregations