0

I am implementing a Room database (because I want to move away from Loaders) and I have a query that selects objects based on the IN operator:

@Query(SELECT * FROM table WHERE icon IN(:icons))
LiveData<List<Result>> getResults(String[] icons);

The issue is that the :icons array is generated dynamically during runtime, first I generate placeholders for it and then replace them with the values, like so:

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    String[] iconsArray = generateIconArray();
    mViewModel = ViewModelProviders.of(this, new MyViewModelFactory(getActivity().getApplication(), iconsArray)).get(MyViewModel.class);
    mViewModel.getResults().observe(this, new Observer<List<Result>>() {
        @Override
        public void onChanged(@Nullable List<Result> results) {
            RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), 3);
            mRecyclerView.setLayoutManager(layoutManager);
            GridAdapter adapter = new GridAdapter(getActivity(), results);
            mRecyclerView.setAdapter(adapter);
        }
    });
}

The problem is that I receive an empty RecyclerView, but when I pass an array with a single icon, the query works normally.
Is it not possible to achieve the same in Room because it checks queries during compile time?
And if not, instead of that should I just use db.query(...) in my repository constructor?

I know this sort of question was asked here, but it also says that they are working on it, and I couldn't find any signs of it.

EDIT:
In case someone stumbles upon this question, I made a small mistake while implementing this feature, the code provided in onActivityCreated actually works. It's also worth mentioning that it works with String[] and lists, but not with a single string: "ab,cd,ef".

Suleyman
  • 2,765
  • 2
  • 18
  • 31
  • "first I generate placeholders for it and then replace them with the values" -- the only placeholder in your query is `:icons`. That is filled in by the `icons` array. What you have there should be fine. Where are you experiencing a problem? – CommonsWare Apr 05 '18 at 12:51
  • @CommonsWare Yes, you are right, basically, in `onActivityCreated` I generate the string array of values and then pass it to `getResults` via `ViewModelFactory`. I also tried replacing `String[]` by just a `String` in a form of `a,b,c,d`, but it doesn't work. The query runs perfectly when I pass just an array with one fixed value, but when I pass an array of several values, it returns nothing. But the main thing is that you say that it is possible in spite of what it says [here](https://stackoverflow.com/questions/45026807/is-there-a-way-to-dynamically-query-the-database)? – Suleyman Apr 05 '18 at 13:34
  • @CommonsWare If it is, then it means I made a stupid mistake somewhere and I will just keep on looking. – Suleyman Apr 05 '18 at 13:35
  • That question is basically asking "can I have a Room query that looks like `SELECT * FROM table WHERE :criterion IN (:values)`?", and the answer is "no". That's not what you have in your question. – CommonsWare Apr 05 '18 at 13:59
  • @CommonsWare Then I have not made myself clear, `icon` is the name of a column, it's not passed dynamically, but `icons` is an array that is generated during runtime. So you are saying that it is not possible, and I should use `db.query(...)`? – Suleyman Apr 05 '18 at 14:22
  • No, I am saying that the question you keep citing is unrelated. I am also saying that `IN` queries work. Your `"a,b,c,d"` approach is incorrect, but `new String[] {"a", "b", "c", "d"}` should be fine. I tend to use either `...` or `ArrayList` rather than `[]`, so it is possible there's a bug unique to `[]`. You might want to consider expanding your question to show how you are actually calling it. – CommonsWare Apr 05 '18 at 14:44
  • @CommonsWare I edited the question to make it more clear. Thank you very much for your help, now that I know that it is possible I will continue on looking for the solution, it's probably a stupid mistake. If you would like to post your comments as an answer I will gladly accept it. And when I find the reason I'll post it. – Suleyman Apr 05 '18 at 15:22
  • Your edit is not calling `getResults()`. – CommonsWare Apr 05 '18 at 15:38
  • @CommonsWare edited. It works! You were right, it is possible, it works with the `String[]` as well, so there is no bug. It was a stupid syntax mistake by me, so the code in the question works. I was afraid it is not possible because with Room queries are verified at compile time. I obviously misunderstood it. Thanks a lot again :) – Suleyman Apr 05 '18 at 16:34

1 Answers1

0

I made a small mistake while implementing this feature, the code provided in onActivityCreated actually works. It's also worth mentioning that it works with String[] and List, but not with a single String: "ab,cd,ef", which was my mistake.

Suleyman
  • 2,765
  • 2
  • 18
  • 31