Skip to content

Commit

Permalink
Fixed: SQLiteConstraintException when inserting the same id item of h…
Browse files Browse the repository at this point in the history
…isotry/notes in room database.

* id is the primary key for notes/history and when there is an already id available in the room database, and if there is the same id present in the objectbox database and we try to put that entity in the room it gives the SQLiteConstraintException. To fix this we have modified our saving functions of history and notes. If there is already an ID that exists in the room database that we are trying to put in the database it will set the ID to 0 so that the room will automatically assign the ID to that entity and our history/notes will prevent to be lost.
* Added the test cases to properly test these scenarios.
  • Loading branch information
MohitMaliDeveloper committed Jun 26, 2024
1 parent 2dd933e commit 15448ac
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,20 @@ class ObjectBoxToRoomMigratorTest {

clearRoomAndBoxStoreDatabases(box)

// Test to insert the items with same id.
val historyItem4 = getHistoryItem(
databaseId = 2,
title = "Main Page",
historyUrl = "https://kiwix.app/A/MainPage"
)
kiwixRoomDatabase.historyRoomDao().saveHistory(historyItem4)
box.put(HistoryEntity(historyItem))
objectBoxToRoomMigrator.migrateHistory(box)
actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().blockingFirst()
assertEquals(2, actualData.size)

clearRoomAndBoxStoreDatabases(box)

// Test migration if ObjectBox has null values
try {
lateinit var invalidHistoryEntity: HistoryEntity
Expand Down Expand Up @@ -348,6 +362,20 @@ class ObjectBoxToRoomMigratorTest {

clearRoomAndBoxStoreDatabases(box)

// Test to insert the items with same id.
val noteItem2 = getNoteListItem(
databaseId = 1,
zimUrl = "http://kiwix.app/Installing",
noteFilePath = "/storage/emulated/0/Download/Notes/Alpine linux/Installing.txt"
)
kiwixRoomDatabase.notesRoomDao().saveNote(noteItem1)
box.put(NotesEntity(noteItem2))
objectBoxToRoomMigrator.migrateNotes(box)
notesList = kiwixRoomDatabase.notesRoomDao().notes().blockingFirst() as List<NoteListItem>
assertEquals(2, notesList.size)

clearRoomAndBoxStoreDatabases(box)

// Test migration if ObjectBox has null values
try {
lateinit var invalidNotesEntity: NotesEntity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,26 @@ class HistoryRoomDaoTest {
assertThat(historyList.size, equalTo(1))
historyRoomDao.deleteAllHistory()

// Save two entity same data and database id but with different date
historyRoomDao.saveHistory(historyItem)
val historyItem1 = getHistoryItem(
title = "Main Page",
historyUrl = "https://kiwix.app/A/MainPage",
databaseId = 1,
dateString = "31 May 2024"
)
historyRoomDao.saveHistory(historyItem1)
historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertThat(historyList.size, equalTo(2))
historyRoomDao.deleteAllHistory()

// Save two entity with same and database id with same date to see if it's updated or not.
historyRoomDao.saveHistory(historyItem)
historyRoomDao.saveHistory(historyItem)
historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertThat(historyList.size, equalTo(1))
historyRoomDao.deleteAllHistory()

// Attempt to save undefined history item
lateinit var undefinedHistoryItem: HistoryListItem.HistoryItem
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import android.content.Context
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.IsEqual.equalTo
Expand Down Expand Up @@ -110,6 +109,24 @@ class NoteRoomDaoTest {
assertEquals(notesList.size, 1)
clearNotes()

// Test to insert the items with same id.
val noteItem2 = getNoteListItem(
databaseId = 1,
zimUrl = "http://kiwix.app/Installing",
noteFilePath = "/storage/emulated/0/Download/Notes/Alpine linux/Installing.txt"
)
val noteItem3 = getNoteListItem(
databaseId = 1,
title = "Installing",
zimUrl = "http://kiwix.app/Installing",
noteFilePath = "/storage/emulated/0/Download/Notes/Alpine linux/Installing.txt"
)
kiwixRoomDatabase.notesRoomDao().saveNote(noteItem2)
kiwixRoomDatabase.notesRoomDao().saveNote(noteItem3)
notesList = notesRoomDao.notes().blockingFirst() as List<NoteListItem>
assertEquals(2, notesList.size)
clearNotes()

// Attempt to save undefined history item
lateinit var undefinedNoteListItem: NoteListItem
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ abstract class HistoryRoomDao : PageDao {
@Insert
abstract fun insertHistoryItem(historyRoomEntity: HistoryRoomEntity)

@Query("SELECT COUNT() FROM HistoryRoomEntity WHERE id = :id")
abstract fun count(id: Int): Int

fun saveHistory(historyItem: HistoryListItem.HistoryItem) {
getHistoryRoomEntity(
historyItem.historyUrl,
Expand All @@ -65,7 +68,12 @@ abstract class HistoryRoomDao : PageDao {
}
updateHistoryItem(it)
} ?: run {
insertHistoryItem(HistoryRoomEntity(historyItem))
val historyEntity = HistoryRoomEntity(historyItem)
if (count(historyEntity.id.toInt()) > 0) {
// set the default id so that room will automatically generates the database id.
historyEntity.id = 0
}
insertHistoryItem(historyEntity)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,17 @@ abstract class NotesRoomDao : PageDao {
deleteNotes(pagesToDelete as List<NoteListItem>)

fun saveNote(noteItem: NoteListItem) {
saveNote(NotesRoomEntity(noteItem))
val notesEntity = NotesRoomEntity(noteItem)
if (count(notesEntity.id.toInt()) > 0) {
// set the default id so that room will automatically generates the database id.
notesEntity.id = 0
}
saveNote(notesEntity)
}

@Query("SELECT COUNT() FROM NotesRoomEntity WHERE id = :id")
abstract fun count(id: Int): Int

@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun saveNote(notesRoomEntity: NotesRoomEntity)

Expand Down

0 comments on commit 15448ac

Please sign in to comment.