public SqlCommand queryFor()

in aws-datastore/src/main/java/com/amplifyframework/datastore/storage/sqlite/SQLiteCommandFactory.java [135:265]


    public SqlCommand queryFor(@NonNull ModelSchema modelSchema,
                               @NonNull QueryOptions options) throws DataStoreException {
        final SQLiteTable table = SQLiteTable.fromSchema(modelSchema);
        final String tableName = table.getName();
        StringBuilder rawQuery = new StringBuilder();
        StringBuilder selectColumns = new StringBuilder();
        StringBuilder joinStatement = new StringBuilder();
        final List<Object> bindings = new ArrayList<>();

        // Track the list of columns to return, along with the alias for the corresponding table
        Map<String, List<SQLiteColumn>> columns = new HashMap<>();
        columns.put(table.getName(), table.getSortedColumns());
        Map<String, Integer> tableCount = new HashMap<>();
        tableCount.put(tableName, 1);

        // Joins the foreign keys
        recursivelyBuildJoins(table, columns, joinStatement, tableCount, tableName);

        // Convert columns to comma-separated column names
        boolean firstTable = true;
        for (String tableAlias : columns.keySet()) {
            if (!firstTable) {
                selectColumns.append(",").append(SqlKeyword.DELIMITER);
            } else {
                firstTable = false;
            }
            Iterator<SQLiteColumn> columnsIterator = Objects.requireNonNull(columns.get(tableAlias)).iterator();
            while (columnsIterator.hasNext()) {
                final SQLiteColumn column = columnsIterator.next();
                String columnName = column.getQuotedColumnName().replace(column.getTableName(), tableAlias);
                selectColumns.append(columnName);
                // Alias columns with a unique alias to avoid duplicate column names or alias names
                String columnAlias = column.getAliasedName()
                        + tableAlias.substring(column.getTableName().length());
                selectColumns.append(SqlKeyword.DELIMITER)
                        .append(SqlKeyword.AS)
                        .append(SqlKeyword.DELIMITER)
                        .append(Wrap.inBackticks(columnAlias));

                if (columnsIterator.hasNext()) {
                    selectColumns.append(",").append(SqlKeyword.DELIMITER);
                }
            }
        }

        // Start SELECT statement.
        // SELECT columns FROM tableName
        rawQuery.append(SqlKeyword.SELECT)
                .append(SqlKeyword.DELIMITER)
                .append(selectColumns.toString())
                .append(SqlKeyword.DELIMITER)
                .append(SqlKeyword.FROM)
                .append(SqlKeyword.DELIMITER)
                .append(Wrap.inBackticks(tableName));

        // Append join statements.
        // INNER JOIN tableOne ON tableName.id=tableOne.foreignKey
        // LEFT JOIN tableTwo ON tableName.id=tableTwo.foreignKey
        if (!joinStatement.toString().isEmpty()) {
            rawQuery.append(SqlKeyword.DELIMITER)
                    .append(joinStatement.toString());
        }

        // Append predicates.
        // WHERE condition
        final QueryPredicate predicate = options.getQueryPredicate();
        if (!QueryPredicates.all().equals(predicate)) {
            final SQLPredicate sqlPredicate = new SQLPredicate(predicate);
            bindings.addAll(sqlPredicate.getBindings());
            String sqlPredicateString = sqlPredicate.toString();
            if (predicate instanceof QueryPredicateOperation) {
                QueryPredicateOperation<?> predicateOperation = (QueryPredicateOperation<?>) predicate;
                String predicateOperationField = predicateOperation.field();
                if (predicateOperationField.equals(PrimaryKey.fieldName()) && predicateOperation.modelName() == null
                        && predicateOperation.operator().type() == QueryOperator.Type.EQUAL) {
                    // The WHERE condition is Where.id("some-ID") but no model name is given.
                    sqlPredicateString = sqlPredicateString.replace(predicateOperationField,
                            tableName + "." + predicateOperationField);
                }
            }
            rawQuery.append(SqlKeyword.DELIMITER)
                    .append(SqlKeyword.WHERE)
                    .append(SqlKeyword.DELIMITER)
                    .append(sqlPredicateString);
        }

        // Append order by
        final List<QuerySortBy> sortByList = options.getSortBy();
        if (sortByList != null) {
            rawQuery.append(SqlKeyword.DELIMITER)
                    .append(SqlKeyword.ORDER_BY)
                    .append(SqlKeyword.DELIMITER);
            Iterator<QuerySortBy> sortByIterator = sortByList.iterator();
            while (sortByIterator.hasNext()) {
                final QuerySortBy sortBy = sortByIterator.next();
                String modelName = Wrap.inBackticks(sortBy.getModelName());
                String fieldName = Wrap.inBackticks(sortBy.getField());
                if (modelName == null) {
                    modelName = Wrap.inBackticks(tableName);
                }
                final String columnName = modelName + "." + fieldName;
                rawQuery.append(columnName)
                        .append(SqlKeyword.DELIMITER)
                        .append(SqlKeyword.fromQuerySortOrder(sortBy.getSortOrder()));

                if (sortByIterator.hasNext()) {
                    rawQuery.append(",")
                            .append(SqlKeyword.DELIMITER);
                }
            }
        }

        // Append pagination after order by
        final QueryPaginationInput paginationInput = options.getPaginationInput();
        if (paginationInput != null) {
            rawQuery.append(SqlKeyword.DELIMITER)
                .append(SqlKeyword.LIMIT)
                .append(SqlKeyword.DELIMITER)
                .append("?")
                .append(SqlKeyword.DELIMITER)
                .append(SqlKeyword.OFFSET)
                .append(SqlKeyword.DELIMITER)
                .append("?");
            bindings.add(paginationInput.getLimit());
            bindings.add(paginationInput.getPage() * paginationInput.getLimit());
        }

        rawQuery.append(";");
        final String queryString = rawQuery.toString();
        return new SqlCommand(table.getName(), queryString, bindings);
    }