use of com.amplifyframework.datastore.storage.sqlite.adapter.SQLiteColumn in project amplify-android by aws-amplify.
the class SQLiteCommandFactory method insertFor.
@NonNull
@Override
public <T extends Model> SqlCommand insertFor(@NonNull ModelSchema modelSchema, @NonNull T item) throws DataStoreException {
final SQLiteTable table = SQLiteTable.fromSchema(modelSchema);
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("INSERT INTO").append(SqlKeyword.DELIMITER).append(Wrap.inBackticks(table.getName())).append(SqlKeyword.DELIMITER).append("(");
final List<SQLiteColumn> columns = table.getSortedColumns();
final Iterator<SQLiteColumn> columnsIterator = columns.iterator();
while (columnsIterator.hasNext()) {
final String columnName = columnsIterator.next().getName();
stringBuilder.append(Wrap.inBackticks(columnName));
if (columnsIterator.hasNext()) {
stringBuilder.append(",").append(SqlKeyword.DELIMITER);
}
}
stringBuilder.append(")").append(SqlKeyword.DELIMITER).append("VALUES").append(SqlKeyword.DELIMITER).append("(");
for (int i = 0; i < columns.size(); i++) {
if (i == columns.size() - 1) {
stringBuilder.append("?");
} else {
stringBuilder.append("?, ");
}
}
stringBuilder.append(")");
final String preparedInsertStatement = stringBuilder.toString();
return new SqlCommand(table.getName(), preparedInsertStatement, // VALUES clause
extractFieldValues(item));
}
use of com.amplifyframework.datastore.storage.sqlite.adapter.SQLiteColumn 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.datastore.storage.sqlite.adapter.SQLiteColumn in project amplify-android by aws-amplify.
the class SQLiteModelFieldTypeConverter method convertValueFromSource.
@Override
public Object convertValueFromSource(@NonNull Cursor cursor, @NonNull ModelField field) throws DataStoreException {
final JavaFieldType javaFieldType = TypeConverter.getJavaFieldType(field);
try {
// Skip if there is no equivalent column for field in object
final SQLiteColumn column = columns.get(field.getName());
if (column == null) {
LOGGER.verbose(String.format("Column with name %s does not exist", field.getName()));
return null;
}
String columnName = column.getAliasedName();
if (javaFieldType == JavaFieldType.MODEL) {
int newInnerModelCount = 1;
String fieldTargetType = field.getTargetType();
if (cursorInnerModelCounts.containsKey(fieldTargetType)) {
Integer currentInnerModelCount = cursorInnerModelCounts.get(fieldTargetType);
newInnerModelCount += currentInnerModelCount == null ? 0 : currentInnerModelCount;
}
cursorInnerModelCounts.put(fieldTargetType, newInnerModelCount);
}
if (isInnerModel && cursorInnerModelCounts.containsKey(parentSchema.getName())) {
Integer modelCount = cursorInnerModelCounts.get(parentSchema.getName());
if (!Objects.equals(modelCount, 1)) {
// More than 1 of the model the field belongs to is present in the cursor
columnName += modelCount;
}
}
final int columnIndex = cursor.getColumnIndexOrThrow(columnName);
// This check is necessary, because primitive values will return 0 even when null
if (cursor.isNull(columnIndex)) {
return null;
}
final String valueAsString = cursor.getString(columnIndex);
LOGGER.verbose(String.format("Attempt to convert value \"%s\" from field %s of type %s in model %s", valueAsString, field.getName(), field.getTargetType(), parentSchema.getName()));
switch(javaFieldType) {
case STRING:
return cursor.getString(columnIndex);
case MODEL:
return convertModelAssociationToTarget(cursor, field);
case ENUM:
return convertEnumValueToTarget(valueAsString, field);
case CUSTOM_TYPE:
return convertCustomTypeToTarget(cursor, field, columnIndex);
case INTEGER:
return cursor.getInt(columnIndex);
case BOOLEAN:
return cursor.getInt(columnIndex) != 0;
case FLOAT:
return cursor.getFloat(columnIndex);
case DOUBLE:
return cursor.getDouble(columnIndex);
case LONG:
return cursor.getLong(columnIndex);
case DATE:
return new Temporal.Date(valueAsString);
case DATE_TIME:
return new Temporal.DateTime(valueAsString);
case TIME:
return new Temporal.Time(valueAsString);
case TIMESTAMP:
return new Temporal.Timestamp(cursor.getLong(columnIndex), TimeUnit.SECONDS);
default:
LOGGER.warn(String.format("Field of type %s is not supported. Fallback to null.", javaFieldType));
return null;
}
} catch (Exception exception) {
throw new DataStoreException(String.format("Error converting field \"%s\" from model \"%s\"", field.getName(), parentSchema.getName()), exception, AmplifyException.REPORT_BUG_TO_AWS_SUGGESTION);
}
}
Aggregations