#Query(
"""
SELECT * FROM t_article ORDER BY
CASE
WHEN :order = 1 THEN id END
"""
)
fun pagingSource(order: Int): PagingSource<Int, Article>
I have the above sql statement code, when I use Ctrl+Alt+L key combination, Android Studio will not format the code of the sql statement.
The code I expect (it may turn out that):
#Query(
"""
SELECT * FROM t_article ORDER BY
CASE WHEN :order = 1 THEN id END
"""
)
fun pagingSource(order: Int): PagingSource<Int, Article>
The version I am using is: Android Studio Electric Eel | 2022.1.1
You can edit how it behaves in Preference->Editor-> Code Style -> desired language (e.g. Kotlin)
Related
I am about the migrate my room database from 1 to 2.
In version 1 exportSchema was set to false. I was unaware of the impact at the time.
Therefore no 1.json schema file is available on device running the app so far.
In version 1 there is a class, let's call it Mango as follows:
#Entity(tableName="mango)
data class Mango(
#PrimaryKey(autoGenerate = true) val id: Int =0,
val carbs: Float = 0f
){...}
In version 2 the field carbs should change to carbohydrate. This is how I do it in my RoomDatabase class.
#Database(
entities = [Mango::class], version = 2, exportSchema = true
)
abstract class AppDatabase : RoomDatabase() {
...
fun getDatabase(
context: Context
): AppDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context,
AppDatabase::class.java,
"my_database"
).addMigrations(MIGRATION_1_2).build()
INSTANCE = instance
instance
}
}
...
val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE Mango RENAME COLUMN cabrs TO carbohydrate")
}
It works on emulator in android studio. And this is how I test it.
Uninstall the app
Run version 1
Switch code to version 2 and run version 2
Result: Working
I have created a release version and sent it via google play to test it in a real life stuation, and I get the following error when I update the app with the new version 2:
Fatal Exception: android.database.sqlite.SQLiteException: near "COLUMN": syntax error (code
1): , while compiling: ALTER TABLE Mango RENAME COLUMN carbs TO carbohydrate
#################################################################
Error Code : 1 (SQLITE_ERROR)
Caused By : SQL(query) error or missing database.
(near "COLUMN": syntax error (code 1): , while compiling: ALTER TABLE Mango RENAME COLUMN
carbs TO carbohydrate).
If it is because of the missing 1.json file, then how can I fix this?
Thanks
If it is because of the missing 1.json file, then how can I fix this?
The issue is probably not the schema but is probably that the "real life run" was on an android version that doesn't include release 3.25.0 or greater of SQLite.
Typically unsupported features result in a Syntax Error that can be confusing is it tends to mention where the error was found as it doesn't know about the new syntax.
i.e. only devices with API 30+ (when a jump was made from 3.22.0 to 3.28.0)
as per https://developer.android.com/reference/android/database/sqlite/package-summary
SQLite 3.25.0 release documentation:-
2018-09-15 (3.25.0)
Add support for window functions
Enhancements the ALTER TABLE command:
Add support for renaming columns within a table using ALTER TABLE table RENAME COLUMN oldname TO newname.
-Fix table rename feature so that it also updates references to the renamed table in triggers and views.
....
If you need to target devices less than API 30, then you may not be able to use AutoMigration but will instead have a manual migration that:-
renames the original table
create the new table (copy the SQL from the createAllTables method in the class that is the same name as the #Database annotated class but suffixed with _Impl that can be found in the java(generated) via the Android View (I believe CRTL B can also be used)).
then execute the SQL INSERT INTO <new_table> SELECT * FROM <the_renamed_original_table>
Note that this assumes that the columns are in exactly the same position. It would be safer to use INSERT INTO new_table (<ALL_THE_COLUMNS_NAMES_OF_THE_NEW_TABLE_COMMA_SEPARATED>) SELECT (<THE_RESPECTIVE_COLUMNS_OF_THE_RENAMED_TABLE_COMMA_SEPARATED>)
Note anything enclosed within < and > should be changed accordingly, the enclosed text explains the change(s)
Note the above is in-principle code, it has not been compiled/run or tested so may contain some minor errors.
I am trying to search a substring using room for example in string "I am eating mutton", I am trying to search "eating" as a substring, I am trying this query, it works fine if I search for exact substring "eating" but doesn't work if I search with "I am eating rice" etc.
#Query("select msg_temp from auto_reply where keyword LIKE '%'||:keyword||'%'")
fun selectKeyword(keyword: String): String
I have seen many answers, all are suggesting same method, even this query works in sqlite browser. Any help should be appreciated
Try using :-
#Query("select msg_temp from auto_reply where keyword LIKE :keyword")
fun selectKeyword(keyword: String): String
and then use
selectKeyword("%eating%")
an alternative (but case sensitive) :-
#Query("select msg_temp from auto_reply where instr(keyword,:keyword)")
wild characters are not considered so just selectKeyword("eating")
another that should work but!!!!
#Query("SELECT * FROM user WHERE name LIKE :wildchar || :name || :wildchar")
fun selectKeyword("eating","%")
#Query("update bookmarks set bookmarks_path= replace(bookmarks_path,:oldPath,:newPath) where bookmarks_path like :oldPath || '%'")
fun updateBookmarksPath(oldPath: String, newPath: String): Completable
I am using the room database and this is my code
I found that the format of this code is not correct when running, android studio prompts me: expression expected, got'replace'
like this
I want to achieve the effect like this
----path------------------path
/root/1/1--------------/stack/1/1
/root/name/1------/stack/name/1
/root/cls/1-----------/stack/cls/1
/root/go/1-----------/stack/go/1
/root/js/1------------/stack/js/1
please
REPLACE is both an SQLite keyword and, in the case of your intended use, the name of a string function: replace() .
The Room annotation processor appears to be rejecting your query string because it is treating replace as keyword instead of function name. Maybe a bug?
Some quick experiments indicate that a possible solution is to surround replace in backticks to mark is as a name (see keyword link above). Please give it a try:
#Query("update bookmarks set bookmarks_path= `replace`(bookmarks_path,:oldPath,:newPath) where bookmarks_path like :oldPath || '%'")
fun updateBookmarksPath(oldPath: String, newPath: String): Completable
in order to cut down on repeated code in my Dao I'm trying to consolidate 4 similar calls into one. I have 4 different queries that are exactly the same except they SELECT a different value from the row. To determine what value I select, I want to pass in a variable which is a string, which corresponds to the entity attribute value:
#Query("""
SELECT :infoType
FROM entry_log
WHERE date >= date(:startDate)
AND date < date(:endDate)
ORDER BY datetime(date) DESC
""")
fun getEntryInfoInDateRange(startDate: String, endDate: String, infoType: String): Observable<List<Int?>>
When I call this, I get back a list with the correct number of elements, but all of them are 0 (which is incorrect)
However, if I have:
SELECT infotypeone
FROM entry_log
WHERE date >= date(:startDate)
AND date < date(:endDate)
ORDER BY datetime(date) DESC
""")
fun getEntryInfoInDateRange(startDate: String, endDate: String, infoType: String): Observable<List<Int?>>
I will be given a list with the correct data (they aren't all 0)
Anyone know if there's some limitation to using parameters in the SELECT field? The parameters in the WHERE/AND fields work just fine
In theory there is one way to do something like you want with #RawQuery. This method has some limitations (for example, you shouldn't expect for type converters to work, and I'm not sure it works seamless with RxJava/LiveData, may be there are others?), but still you can try.
From documentation:
If you know the query at compile time, you should always prefer Query since it validates the query at compile time and also generates more efficient code since Room can compute the query result at compile time
On the other hand, RawQuery serves as an escape hatch where you can build your own SQL query at runtime but still use Room to convert it into objects.
In your Dao there would be two methods (you can play with Observable, but I'm not sure it can digest that):
#RawQuery
fun getEntryInfoInDateRangeTemplate(query: SupportSQLiteQuery): Observable<List<Int>>
fun getEntryInfoInDateRange(startDate: String, endDate: String, infoType: String):Observable<List<Int?>> {
val query =
"""
SELECT infoType
FROM entry_log
WHERE date >= date(?startDate)
AND date < date(?endDate)
ORDER BY datetime(date) DESC
""".replace("infoType", infoType)
return getEntryInfoInDateRangeTemplate(SimpleSQLiteQuery(query, arrayOf(startDate, endDate)))
}
And as a result you can call the second method from Repository/ViewModel.
I am loading a set of data from db using room and pagedList since it is a large set. I need to filter that data and show it to the user accordingly using the same pagedlistadapter. Please help.
dao is as follows
#WorkerThread
#Query("SELECT * FROM users WHERE name LIKE :query ORDER BY id DESC")
fun getAll(query: String): DataSource.Factory<Int, users>
Table has 4 fields - id,name,phone,address
You should use Transformations.switchMap() to requery the database any time the search term changes:
https://github.com/gavingt/upcoming-games/blob/cd7af7fbdd60933991ea7f8b966ca171bb594cb3/app/src/main/java/com/gavinsappcreations/upcominggames/ui/list/ListViewModel.kt#L35
Or see Google's Paging Library codelab, which does the same thing:
https://codelabs.developers.google.com/codelabs/android-paging/index.html?index=..%2F..%2Findex#1
#Query("SELECT * FROM users WHERE name LIKE :query ORDER BY id DESC")
fun getAll(query: String): DataSource.Factory<Int, users>
Here's your query string must be like %ABC% where abc is the name of the user.
The LIKE key word is use to check/find the pattern in the records Here you can read the possible pattern searches
To attach the % % to your query string you need to call this function as
YOUR_HELPER.getAll("%".plus(YOUR_QUERY).plus("%"))
plus() uses for Concatenation.