web-dev-qa-db-fra.com

Requête booléenne en hardcode dans la base de données de la pièce

Je suis en train de construire une application Android qui affiche une liste de correspondances potentielles pour un utilisateur. L'utilisateur peut cliquer sur l'une d'elles pour l'aimer, et je sauvegarde tous ces goûts au niveau local.

Je peux écrire une requête pour obtenir la liste des correspondances comme ceci:

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

J'ai appris que cela fonctionne bien. Cependant, je ne prévois pas de scénario dans lequel je définirais jamais liked sur false. Je suis donc curieux de savoir s'il existe un moyen de coder en dur ma condition booléenne? Si j'essaye:

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

J'obtiens l'erreur suivante lors de la compilation:

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

Comment puis-je coder ce booléen en dur dans ma chaîne de requête?

J'ai aussi essayé:

  • Enveloppant la condition entre guillemets simples
    • @Query("SELECT * FROM match WHERE liked = 'true' ORDER BY match DESC LIMIT :limit")
41
AdamMc331

SQLite n'a pas de type de données booléen. La salle le mappe dans une colonne INTEGER et mappe true à 1 et false à 0.

Donc, je m'attendrais à ce que cela fonctionne:

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

Gardez à l'esprit que ce comportement n'est pas documenté. Toutefois, cela ne devrait pas changer - du moins pas sans que les klaxons d’alarme sonnent - car nous aurions besoin de recourir aux migrations pour faire face aux changements.

127
CommonsWare

L’approche de CommonWare fonctionne et répond également directement à la question des PO; Cependant, je ne suis pas fan de faire une telle hypothèse sur la base de données. Cette hypothèse devrait être sûre, mais cela pourrait créer un travail inattendu si Room décidait de modifier sa mise en œuvre booléenne.

Je suggérerais que la meilleure approche consiste à ne pas coder en dur le booléen 1 ou 0 dans la requête. Si la base de données se trouve derrière un référentiel, il est toujours possible pour le référentiel d'exposer une API élégante. Personnellement, je pense que de toute façon, protéger l’ensemble de la base de code de la base de données est une bonne chose.

Dao Method (copié de la question de OP)

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

Dépôt

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

Bien sûr, il s’agit d’une option éclairée dans la mesure où elle suppose un certain style architectural. Cependant, il ne fait pas d'hypothèses sur la base de données interne. Même sans le référentiel qui protège la base de données, l'appel peut être effectué dans la base de données en passant vrai partout - également sans émettre d'hypothèses sur les données sous-jacentes.

13
methodsignature