Dynamically build query in Room - android

Question
Is it possible to dynamically build the filtering for a query?
The problem
I have a big list, addresses. The user can filter it with typing text in a SearchView. If the user put any space in the text it will be divided and the two part of the text will be searched separately. I have to build the SQL dynamically because I didn't know how many space characters will be. Is there any way to handle this in Room whit simple #Query or I have to use #RawQuery for this?
Example SQL for this:
SELECT * FROM ADDRESS WHERE (CITY LIKE '%abc%' OR STREET LIKE '%abc%') AND (CITY LIKE '%abc%' OR STREET LIKE '%def%') AND (....)

I think what you should do is use RawQuery.
Since your query is complicated and you are not sure how long it is, you should probably construct it in runtime and execute it as well.
Room check the validity of the #Query in compile time so I think you'll have a hard time to implement it that way.
This example is taken from the documentation:
#Dao
interface RawDao {
#RawQuery
User getUserViaQuery(SupportSQLiteQuery query);
}
SimpleSQLiteQuery query = new SimpleSQLiteQuery("SELECT * FROM User WHERE id = ? LIMIT 1", new Object[]{userId});
User user2 = rawDao.getUserViaQuery(query);

You can pass those words in an array
#Query("SELECT * FROM ADDRESS WHERE CITY LIKE(:keywords)") //customize your query here
List addresses(String[] keywords);

Related

Android Room Advanced Query with list and multiple conditions

i have a query like this
#Query("SELECT * FROM table WHERE type IN(:types) AND selection = 0 ORDER BY timestamp DESC")
my problem is that i have one type in my type list lets say it's type=4 for which i want selection = 1.
Is it possible to get the results in one query and how should the query look like?

Android Room list of keyword search

I need to search a list of keyword in Room. Currently i can search a single keyword like:
#Query("SELECT * FROM customer where content LIKE '%' || :keyword || '%' and status = 'published'")
LiveData<List<Customer>> getSearchResult(String keyword);
But how can i search a list of keyword in a easy way.
Is there easy way like IN with Collection arguments like:
#Query("SELECT first_name, last_name FROM user WHERE region IN (:regions)")
public List<NameTuple> loadUsersFromRegions(List<String> regions);
I know i can build query for multiple keyword manually but i want to pass a Collection as a argument.
Thanks in advance.
In SQL this is an easy thing to do by using FTS3 or FTS4 it's a Full Text Search these two are the newest features in SQL but I'm struggling on how to configure this into my android projects. I under stand a bit about room but not enough to give a an accurate answer I'm still researching this myself but have not found an answer. Please let me know if you find a way to configure it. I've been on this issue for weeks now but I know from knowing more about SQL that it is the FTS functions that are needed.
I have used below code for FTS search. Joined keyword with OR
String keywordAll = TextUtils.join("* OR *", keywordList);
keywordAll = "*" + keywordAll + "*";
For query used MATCH for search
WHERE Posts MATCH :keyword
Hope this will help others.

How to do search in Room data base?

I have created a room database, and showed my data in a RecyclerView. I know how to add, delete, deleteAll, update data in room data base, but the problem is I don't know how to perform search in room data base?
I have added a search view in the tool bar. But I don't know how to add Queries in NoteDao and the remaining classes, e.g. in my adpter, MainActivity etc.
If you're able to show your Room database in the RecyclerView, this would mean you should know how to use the #Query() tag for fetching your data.
Searching is done using the same #Query tag using the WHERE keyword.
For example, if you wish to find a specific note:
#Query("SELECT * FROM notes WHERE id == :id")
public Note getNote(String id)
However, that's just the simplest way to use WHERE. Frequently, you'll be combining it with other keywords such as IN, LIKE, or BETWEEN.
So for your situation of using a search, you would most likely want to use the LIKE keyword, which can query your database for a field that contains parts of its data that matches the search criteria:
For example:
#Query("SELECT * FROM notes WHERE note_title LIKE :search OR note_message LIKE :search")
public List<Note> getSearchedNote(String search)
This would search your database and return a list of Notes that has either a Note Title or a Note Message that contains the search term you want.

ORMLite union operator

I have three tables that I have to present in one Android ListView. To get the data I use the SQL UNION operator to "merge" all three tables together, so that in my ViewBinder I can make each timeline item look distinct.
These items need to be sorted in chronological order. These three tables do not have a common base class.
Here is the SQL that I have in mind:
SELECT * FROM (
SELECT id, startTime as time, username, comment, "CustomerInteraction" FROM CustomerInteraction
UNION
SELECT id, date as time, "" as username, "" as comment, "Sale" FROM Sale
UNION
SELECT id, claimDate as time, username, comment, "TravelClaim" FROM TravelClaim)
ORDER BY time DESC LIMIT 100
How can I express the above query in ORMLite?
I know I can use Dao.executeRaw, but I don't want to populate my entire list in one go. I would much rather use the trick to get the underlying cursor from ORMLite, and then just pass that to my Adapter. (Lazy loading, makes initial display of long lists much faster.)
Is there a way I can do something like Dao.getPreparedQueryFromRaw(String statement) ? Or better yet QueryBuilder.union(QueryBuilder qb)?
You can get a Cursor by calling rawQuery on the SQLiteDatabase. I do something like this:
final SQLiteDatabase db = getHelper().getReadableDatabase();
Cursor cursor = db.rawQuery(MY_SQL_QUERY, null);
You don't need to do anything much more than that.
Is there a way I can do something like Dao.getPreparedQueryFromRaw(String statement) ? Or better yet QueryBuilder.union(QueryBuilder qb)?
The best way to do this with ORMLite is with one of the the queryRaw(...) methods. They return a GenericRawResults class which you can iterate across. The iterator gives you a number of different methods to help with moving around the list.
The problem is that the generic results are not of a certain type so I'm not sure if you can map it into the Android ListView. You can provide a RawRowMapper to queryRaw(...). You can get the mapper for a particular type by using the dao.getRawRowMapper() method.
Hope something here is helpful.

How to query similar records in SQLite database from Android?

Let's say an SQLite database column contains the following value:
U Walther-Schreiber-Platz
Using a query I'd like to find this record, or any similar records, if the user searches for the following strings:
walther schreiber
u walther
walther-schreiber platz
[Any other similar strings]
However I cannot figure out any query which would do that. Especially if the user does not enter the - character.
Example:
select * from myTable where value like '%walther schreiber%'; would not return the result because of the missing -.
Thanks,
Robert
So, as I said in my comment, I think you can have a query along the lines of:
select * from myTable where LOWER(value) like <SearchValue>
I'm assuming you're collecting the <SearchValue> from the user programmatically, so would be able to do the following: <SearchValue> would need to be: The user's search string, appropriately cleansed to avoid SQL injection attacks, converted to lower case, with all of the spaces converted to '%', so that they match zero or more characters...
So you would have (for example):
select * from myTable where LOWER(value) like '%walther%schreiber%'
select * from myTable where LOWER(value) like '%walther-schreiber%platz%'
etc... however, this does assume that the word order is the same, which in your examples it is...

Categories

Resources