0

Recently I faced a situation that need to query for specific object type but without passing it with method I could not find any way. So I want to do some thing like:

@Query(" select * from table_a where type = ENUM_A")
fun queryForTypeA()

But its alternative bellow is works but I do not want to pass any thing.

@Query(" select * from table_a where type =:type")
fun queryForTypeA(type: EnumType = ENUM_A)

The thing is if I find out the proper way in some other query I wanna exclude some other ENUMs so passing in function is not working there and no sense. I wanna achieve something like this:

@Query(" select * from table_a where type NOT ENUM_A")
fun queryForAllTypesExceptA()
Mahdi
  • 6,139
  • 9
  • 57
  • 109

3 Answers3

0

Try altering the second approach, but define a default value for type like:

@Query(" select * from table_a where type =:type")
fun queryForTypeA(type: EnumType = EnumType.A)

This way you don't have to specify a value for type at the call sites.

homerman
  • 3,369
  • 1
  • 16
  • 32
  • I also did this but did not mention. So looking for passing hardcoded value to query. the reason is in some query I wanna exclude some others so I have to add list of enum in exclude query so that not making sense. – Mahdi Mar 29 '21 at 04:23
0

enums are static constants but are not compile-time constants. Just like any other classes enum is loaded when the first time needed.

you can't have dynamically defined arguments for your @Query annotation.

You can either put your type in a companion object of class or you can use sealed class like here

@Query(" select * from table_a where type"+ "="+ companionEnum_a) 
fun queryForTypeA() 

Make sure your companionEnum_a is compile-time constant. That is it should be const val companionEnum_a

End User
  • 792
  • 6
  • 14
  • Can you gimme the source link of your quota comment? – Mahdi Mar 29 '21 at 07:05
  • https://stackoverflow.com/questions/28296547/execution-order-of-enum-in-java/28296706#28296706 – End User Mar 29 '21 at 07:06
  • For sure, let me try your solution. – Mahdi Mar 29 '21 at 08:35
  • If you mean create scaled class and put it in companion object, still I got 'Annotation argument must be compile time" and still can not put them in query. :( – Mahdi Mar 29 '21 at 08:50
  • You can just use a normal class with companion object – End User Mar 29 '21 at 08:54
  • It is not working. You can just test it your self, try to pass any companion object in room dao queris. – Mahdi Mar 29 '21 at 08:57
  • In any room dao as my example in question I try to pass that companion object as "...= $companionObject " – Mahdi Mar 29 '21 at 09:12
  • @Query(" select * from table_a where type = $companionEnum_a ") fun queryForTypeA() – Mahdi Mar 29 '21 at 09:13
  • @Mahdi I have updated the answer for you. I have checked it and it's working fine – End User Mar 29 '21 at 16:58
  • This code can never compile, how did you + in strings and pass enum?! – Mahdi Mar 30 '21 at 05:14
  • I thought we are clear that you can't use enum in-room query make string const in the companion object. it's a simple string concatenation – End User Mar 30 '21 at 10:30
  • Do you think my problem was companion object?! For sure I was using companion object as beginnings for passing, but for enum value it wont accept string as enum or any object that we have type convertor for it. I will see error like: "SQL error or missing database (no such column: enum_1)" – Mahdi Mar 31 '21 at 05:04
  • Don't use enum, you can't. use string that's what I'm saying – End User Mar 31 '21 at 05:06
  • But Room wont recognize my string as Enum. – Mahdi Mar 31 '21 at 05:08
  • Yes it won't , because you can't do that . You must use string not enum – End User Mar 31 '21 at 05:09
  • I mean if I pass string as field of enum room wont compile it, so do you mean that I have to change my field to string in table so that can make this work?! – Mahdi Mar 31 '21 at 05:13
  • Yes , because room can't understand enum – End User Mar 31 '21 at 05:16
  • Mmm we just back to my question first point. So your answer not helping me, I can not change whole tables to string so that can use string in query. – Mahdi Mar 31 '21 at 05:22
0

Okey after lots of tries I found that I can pass object or enum equal value I created in type convertor as fixed string. Because best way of saving complicated classes or enum is save them as String so we create two methods one is fromString(value: String):MyEnum and second is toString(value:MyEnum):String in typeConvertor class.

Seems that Room can convert that string value using type convertors. So I changed to like this and it works:

@Query(" select * from table_a where type != 'ENUM_A' ")
fun queryForAllTypesExceptA()

And another point that NOT won't work for it and you have to use !=

Mahdi
  • 6,139
  • 9
  • 57
  • 109