Жесткий код Логический запрос в базе данных

Я создаю приложение для Android, которое отображает список потенциальных совпадений для пользователя. Пользователь может нажать на один, чтобы понравиться пользователю, и я сохраняю все эти локальные локальные.

Я могу написать запрос, чтобы получить список таких совпадений:

@Query("SELECT * FROM match WHERE liked = :liked ORDER BY match DESC LIMIT :limit")
fun getMatches(limit: Int = 6, liked: Boolean = true): Flowable<List<Match>>

Я узнал, что это работает отлично. Тем не менее, я не предвижу какой-либо сценарий, когда мне когда-нибудь liked false, и поэтому мне любопытно, есть ли способ жестко кодировать мое логическое состояние? Если я попробую:

@Query("SELECT * FROM match WHERE liked = true ORDER BY match DESC LIMIT :limit")

Во время компиляции я получаю следующую ошибку:

Error:(8, 0) Gradle: error: There is a problem with the query: [SQLITE_ERROR] SQL error or missing database (no such column: true)

Как я могу скопировать этот Boolean в строку запроса?

Я также пробовал:

  • Объединение условия в одинарные кавычки
    • @Query("SELECT * FROM match WHERE liked = 'true' ORDER BY match DESC LIMIT :limit")

Ответ 1

SQLite не имеет логического типа данных. Комната сопоставляет его с столбцом INTEGER, отображая true для 1 и false - 0.

Поэтому я бы ожидал, что это сработает:

@Query("SELECT * FROM match WHERE liked = 1 ORDER BY match DESC LIMIT :limit")

Имейте в виду, что это поведение недокументировано. Тем не менее, он не должен меняться - по крайней мере, не без тревожного зондирования, - так как нам нужно будет использовать миграции, чтобы справляться с любыми изменениями.

Ответ 2

Подход CommonWare работает, а также напрямую отвечает на вопрос OPs; однако я не являюсь поклонником такого предположения о базе данных. Это предположение должно быть безопасным, но оно может создать неожиданную работу по дороге, если Room когда-либо решит изменить ее логическую реализацию.

Я бы предложил, чтобы лучший подход заключался в том, чтобы не перекодировать логический 1 или 0 в запрос. Если база данных находится за репозиторием, репозиторий по-прежнему может выставлять изящный API. Лично я считаю, что защищать большую базу кода от реализации базы данных все равно хорошо.

Метод Дао (скопирован из вопроса ОП)

@Query("SELECT * FROM match WHERE liked = :liked ORDER BY match DESC LIMIT :limit")
fun getMatches(limit: Int = 6, liked: Boolean = true): Flowable<List<Match>>

вместилище

class Repository {
    public Flowable<List<Match>> getLikedMatches() {
        return dao.getMatches(6, true);
    }
}

Конечно, это упрямый вариант в том, что он предполагает определенный архитектурный стиль. Однако он не делает предположений о внутренней базе данных. Даже без защитного хранилища базы данных вызов может быть внесен в базу данных, передавая всюду всюду - также без предположений относительно базовых данных.