Skip to content

Commit

Permalink
Merge pull request #29 from xizzhu/book-short-name
Browse files Browse the repository at this point in the history
book short name
  • Loading branch information
xizzhu committed Mar 30, 2019
2 parents 7d36c27 + 3ad6679 commit 7d15059
Show file tree
Hide file tree
Showing 24 changed files with 141 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,23 +95,26 @@ class AndroidReadingStorageTest : BaseSqliteTest() {
fun testReadBookNamesFromNonExistTranslation() {
runBlocking {
assertTrue(androidReadingStorage.readBookNames("not_exist").isEmpty())
assertTrue(androidReadingStorage.readBookShortNames("not_exist").isEmpty())
}
}

@Test
fun testSaveThenReadBookNames() {
runBlocking {
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, MockContents.kjvBookNames)
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, MockContents.kjvBookNames, MockContents.kjvBookShortNames)
assertEquals(MockContents.kjvBookNames, androidReadingStorage.readBookNames(MockContents.kjvShortName))
assertEquals(MockContents.kjvBookShortNames, androidReadingStorage.readBookShortNames(MockContents.kjvShortName))
}
}

@Test
fun testSaveOverrideThenReadBookNames() {
runBlocking {
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, listOf("random_1", "whatever_2"))
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, MockContents.kjvBookNames)
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, listOf("random_1", "whatever_2"), listOf("ok_3", "fine_4"))
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, MockContents.kjvBookNames, MockContents.kjvBookShortNames)
assertEquals(MockContents.kjvBookNames, androidReadingStorage.readBookNames(MockContents.kjvShortName))
assertEquals(MockContents.kjvBookShortNames, androidReadingStorage.readBookShortNames(MockContents.kjvShortName))
}
}

Expand Down Expand Up @@ -151,11 +154,11 @@ class AndroidReadingStorageTest : BaseSqliteTest() {
@Test
fun testSaveThenReadWithParallelTranslations() {
runBlocking {
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, MockContents.kjvBookNames)
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, MockContents.kjvBookNames, MockContents.kjvBookShortNames)
androidDatabase.translationDao.createTable(MockContents.kjvShortName)
androidDatabase.translationDao.save(MockContents.kjvShortName, MockContents.kjvVerses.toMap())

androidDatabase.bookNamesDao.save(MockContents.cuvShortName, MockContents.cuvBookNames)
androidDatabase.bookNamesDao.save(MockContents.cuvShortName, MockContents.cuvBookNames, MockContents.cuvBookShortNames)
androidDatabase.translationDao.createTable(MockContents.cuvShortName)
androidDatabase.translationDao.save(MockContents.cuvShortName, MockContents.cuvVerses.toMap())

Expand All @@ -171,11 +174,11 @@ class AndroidReadingStorageTest : BaseSqliteTest() {
@Test
fun testSaveThenReadByVerseIndex() {
runBlocking {
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, MockContents.kjvBookNames)
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, MockContents.kjvBookNames, MockContents.kjvBookShortNames)
androidDatabase.translationDao.createTable(MockContents.kjvShortName)
androidDatabase.translationDao.save(MockContents.kjvShortName, MockContents.kjvVerses.toMap())

androidDatabase.bookNamesDao.save(MockContents.cuvShortName, MockContents.cuvBookNames)
androidDatabase.bookNamesDao.save(MockContents.cuvShortName, MockContents.cuvBookNames, MockContents.cuvBookShortNames)
androidDatabase.translationDao.createTable(MockContents.cuvShortName)
androidDatabase.translationDao.save(MockContents.cuvShortName, MockContents.cuvVerses.toMap())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class AndroidTranslationStorageTest : BaseSqliteTest() {
fun testSaveTranslationThenRead() {
runBlocking {
androidTranslationStorage.saveTranslation(MockContents.kjvDownloadedTranslationInfo,
MockContents.kjvBookNames, MockContents.kjvVerses.toMap())
MockContents.kjvBookNames, MockContents.kjvBookShortNames, MockContents.kjvVerses.toMap())

val actual = androidTranslationStorage.readTranslations()
assertEquals(1, actual.size)
Expand All @@ -84,7 +84,7 @@ class AndroidTranslationStorageTest : BaseSqliteTest() {
fun testSaveTranslationWithDownloadedFalseThenRead() {
runBlocking {
androidTranslationStorage.saveTranslation(MockContents.kjvTranslationInfo,
MockContents.kjvBookNames, MockContents.kjvVerses.toMap())
MockContents.kjvBookNames, MockContents.kjvBookShortNames, MockContents.kjvVerses.toMap())

val actual = androidTranslationStorage.readTranslations()
assertEquals(1, actual.size)
Expand All @@ -105,7 +105,7 @@ class AndroidTranslationStorageTest : BaseSqliteTest() {
fun testRemoveTranslation() {
runBlocking {
androidTranslationStorage.saveTranslation(MockContents.kjvTranslationInfo,
MockContents.kjvBookNames, MockContents.kjvVerses.toMap())
MockContents.kjvBookNames, MockContents.kjvBookShortNames, MockContents.kjvVerses.toMap())
assertTrue(androidDatabase.readableDatabase.hasTable(MockContents.kjvShortName))
assertEquals(MockContents.kjvBookNames, androidDatabase.bookNamesDao.read(MockContents.kjvShortName))
assertEquals(MockContents.kjvVerses, androidDatabase.translationDao.read(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class BookNamesDaoTest : BaseSqliteTest() {
@Test
fun testEmptyTable() {
assertTrue(androidDatabase.bookNamesDao.read("not_exist").isEmpty())
assertTrue(androidDatabase.bookNamesDao.readShortName("not_exist").isEmpty())

for (bookIndex in 0 until Bible.BOOK_COUNT) {
assertTrue(androidDatabase.bookNamesDao.read(bookIndex).isEmpty())
Expand All @@ -41,42 +42,44 @@ class BookNamesDaoTest : BaseSqliteTest() {
@Test
fun testSaveThenRead() {
val translationShortName = MockContents.kjvShortName
androidDatabase.bookNamesDao.save(translationShortName, MockContents.kjvBookNames)
androidDatabase.bookNamesDao.save(translationShortName, MockContents.kjvBookNames, MockContents.kjvBookShortNames)
assertEquals(MockContents.kjvBookNames, androidDatabase.bookNamesDao.read(translationShortName))
assertEquals(MockContents.kjvBookShortNames, androidDatabase.bookNamesDao.readShortName(translationShortName))
}

@Test
fun testSaveOverrideThenReadBookNames() {
val translationShortName = MockContents.kjvShortName
androidDatabase.bookNamesDao.save(translationShortName, listOf("random_1", "whatever_2"))
androidDatabase.bookNamesDao.save(translationShortName, MockContents.kjvBookNames)
androidDatabase.bookNamesDao.save(translationShortName, listOf("random_1", "whatever_2"), listOf("ok_3", "fine_4"))
androidDatabase.bookNamesDao.save(translationShortName, MockContents.kjvBookNames, MockContents.kjvBookShortNames)
assertEquals(MockContents.kjvBookNames, androidDatabase.bookNamesDao.read(translationShortName))
assertEquals(MockContents.kjvBookShortNames, androidDatabase.bookNamesDao.readShortName(translationShortName))
}

@Test
fun testSaveThenReadParallel() {
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, MockContents.kjvBookNames)
androidDatabase.bookNamesDao.save(MockContents.cuvShortName, MockContents.cuvBookNames)
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, MockContents.kjvBookNames, MockContents.kjvBookShortNames)
androidDatabase.bookNamesDao.save(MockContents.cuvShortName, MockContents.cuvBookNames, MockContents.cuvBookShortNames)
assertEquals(mapOf(Pair(MockContents.kjvShortName, MockContents.kjvBookNames[1]),
Pair(MockContents.cuvShortName, MockContents.cuvBookNames[1])),
androidDatabase.bookNamesDao.read(listOf(MockContents.kjvShortName, MockContents.cuvShortName), 1))
}

@Test
fun testSaveOverrideThenReadParallel() {
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, listOf("random_1", "whatever_2"))
androidDatabase.bookNamesDao.save(MockContents.cuvShortName, listOf("random_3", "whatever_4"))
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, MockContents.kjvBookNames)
androidDatabase.bookNamesDao.save(MockContents.cuvShortName, MockContents.cuvBookNames)
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, listOf("random_1", "whatever_2"), listOf("ok_3", "fine_4"))
androidDatabase.bookNamesDao.save(MockContents.cuvShortName, listOf("random_3", "whatever_4"), listOf("ok_1", "fine_2"))
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, MockContents.kjvBookNames, MockContents.kjvBookShortNames)
androidDatabase.bookNamesDao.save(MockContents.cuvShortName, MockContents.cuvBookNames, MockContents.cuvBookShortNames)
assertEquals(mapOf(Pair(MockContents.kjvShortName, MockContents.kjvBookNames[1]),
Pair(MockContents.cuvShortName, MockContents.cuvBookNames[1])),
androidDatabase.bookNamesDao.read(listOf(MockContents.kjvShortName, MockContents.cuvShortName), 1))
}

@Test
fun testSaveThenReadByBookIndex() {
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, MockContents.kjvBookNames)
androidDatabase.bookNamesDao.save(MockContents.cuvShortName, MockContents.cuvBookNames)
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, MockContents.kjvBookNames, MockContents.kjvBookShortNames)
androidDatabase.bookNamesDao.save(MockContents.cuvShortName, MockContents.cuvBookNames, MockContents.cuvBookShortNames)

val expected = mapOf(Pair(MockContents.kjvShortName, MockContents.kjvBookNames[0]),
Pair(MockContents.cuvShortName, MockContents.cuvBookNames[0]))
Expand All @@ -86,10 +89,10 @@ class BookNamesDaoTest : BaseSqliteTest() {

@Test
fun testSaveOverrideThenReadByBookIndex() {
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, listOf("random_1", "whatever_2"))
androidDatabase.bookNamesDao.save(MockContents.cuvShortName, listOf("random_3", "whatever_4"))
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, MockContents.kjvBookNames)
androidDatabase.bookNamesDao.save(MockContents.cuvShortName, MockContents.cuvBookNames)
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, listOf("random_1", "whatever_2"), listOf("ok_3", "fine_4"))
androidDatabase.bookNamesDao.save(MockContents.cuvShortName, listOf("random_3", "whatever_4"), listOf("ok_2", "fine_1"))
androidDatabase.bookNamesDao.save(MockContents.kjvShortName, MockContents.kjvBookNames, MockContents.kjvBookShortNames)
androidDatabase.bookNamesDao.save(MockContents.cuvShortName, MockContents.cuvBookNames, MockContents.cuvBookShortNames)

val expected = mapOf(Pair(MockContents.kjvShortName, MockContents.kjvBookNames[0]),
Pair(MockContents.cuvShortName, MockContents.cuvBookNames[0]))
Expand All @@ -102,15 +105,18 @@ class BookNamesDaoTest : BaseSqliteTest() {
val translationShortName = "not_exist"
androidDatabase.bookNamesDao.remove(translationShortName)
assertTrue(androidDatabase.bookNamesDao.read(translationShortName).isEmpty())
assertTrue(androidDatabase.bookNamesDao.readShortName(translationShortName).isEmpty())
}

@Test
fun testSaveThenRemove() {
val translationShortName = MockContents.kjvShortName
androidDatabase.bookNamesDao.save(translationShortName, MockContents.kjvBookNames)
androidDatabase.bookNamesDao.save(translationShortName, MockContents.kjvBookNames, MockContents.kjvBookShortNames)
assertEquals(MockContents.kjvBookNames, androidDatabase.bookNamesDao.read(translationShortName))
assertEquals(MockContents.kjvBookShortNames, androidDatabase.bookNamesDao.readShortName(translationShortName))

androidDatabase.bookNamesDao.remove(translationShortName)
assertTrue(androidDatabase.bookNamesDao.read(translationShortName).isEmpty())
assertTrue(androidDatabase.bookNamesDao.readShortName(translationShortName).isEmpty())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ class BibleReadingManager(private val bibleReadingRepository: BibleReadingReposi
suspend fun readBookNames(translationShortName: String): List<String> =
bibleReadingRepository.readBookNames(translationShortName)

suspend fun readBookShortNames(translationShortName: String): List<String> =
bibleReadingRepository.readBookShortNames(translationShortName)

suspend fun readVerses(translationShortName: String, bookIndex: Int, chapterIndex: Int): List<Verse> =
bibleReadingRepository.readVerses(translationShortName, bookIndex, chapterIndex)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ class BibleReadingRepository(private val localReadingStorage: LocalReadingStorag
return length
}
}
private val bookShortNamesCache = object : LruCache<String, List<String>>((maxMemory / 16L).toInt()) {
override fun sizeOf(key: String, bookShortNames: List<String>): Int {
// strings are UTF-16 encoded (with a length of one or two 16-bit code units)
var length = 0
for (bookName in bookShortNames) {
length += bookName.length * 4
}
return length
}
}
private val versesCache = object : LruCache<String, List<Verse>>((maxMemory / 8L).toInt()) {
override fun sizeOf(key: String, verses: List<Verse>): Int {
// each Verse contains 3 integers and 2 strings (we don't cache parallel translations yet)
Expand Down Expand Up @@ -66,6 +76,15 @@ class BibleReadingRepository(private val localReadingStorage: LocalReadingStorag
return bookNames
}

suspend fun readBookShortNames(translationShortName: String): List<String> {
var bookShortNames = bookShortNamesCache.get(translationShortName)
if (bookShortNames == null) {
bookShortNames = localReadingStorage.readBookShortNames(translationShortName)
bookShortNamesCache.put(translationShortName, bookShortNames)
}
return bookShortNames
}

suspend fun readVerses(translationShortName: String, bookIndex: Int, chapterIndex: Int): List<Verse> {
val key = "$translationShortName-$bookIndex-$chapterIndex"
var verses = versesCache.get(key)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class TranslationRepository(private val localTranslationStorage: LocalTranslatio
channel.send(100)

localTranslationStorage.saveTranslation(translation.translationInfo.toTranslationInfo(true),
translation.bookNames, translation.verses)
translation.bookNames, translation.bookShortNames, translation.verses)
}

suspend fun removeTranslation(translationInfo: TranslationInfo) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ interface LocalReadingStorage {

suspend fun readBookNames(translationShortName: String): List<String>

suspend fun readBookShortNames(translationShortName: String): List<String>

suspend fun readVerses(translationShortName: String, bookIndex: Int, chapterIndex: Int, bookName: String): List<Verse>

suspend fun readVerses(translationShortName: String, parallelTranslations: List<String>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ interface LocalTranslationStorage {

suspend fun saveTranslation(translationInfo: TranslationInfo,
bookNames: List<String>,
bookShortNames: List<String>,
verses: Map<Pair<Int, Int>, List<String>>)

suspend fun removeTranslation(translationInfo: TranslationInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ class AndroidReadingStorage(private val androidDatabase: AndroidDatabase) : Loca
}
}

override suspend fun readBookShortNames(translationShortName: String): List<String> {
return withContext(Dispatchers.IO) {
androidDatabase.bookNamesDao.readShortName(translationShortName)
}
}

override suspend fun readVerses(translationShortName: String, bookIndex: Int,
chapterIndex: Int, bookName: String): List<Verse> {
return withContext(Dispatchers.IO) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,17 @@ class AndroidTranslationStorage(private val androidDatabase: AndroidDatabase) :
}
}

override suspend fun saveTranslation(translationInfo: TranslationInfo, bookNames: List<String>,
override suspend fun saveTranslation(translationInfo: TranslationInfo,
bookNames: List<String>,
bookShortNames: List<String>,
verses: Map<Pair<Int, Int>, List<String>>) {
withContext(Dispatchers.IO) {
var db: SQLiteDatabase? = null
try {
db = androidDatabase.writableDatabase
db.beginTransaction()

androidDatabase.bookNamesDao.save(translationInfo.shortName, bookNames)
androidDatabase.bookNamesDao.save(translationInfo.shortName, bookNames, bookShortNames)
if (translationInfo.downloaded) {
androidDatabase.translationInfoDao.save(translationInfo)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ class BookNamesDao(private val sqliteHelper: SQLiteOpenHelper) {
private const val COLUMN_TRANSLATION_SHORT_NAME = "translationShortName"
private const val COLUMN_BOOK_INDEX = "bookIndex"
private const val COLUMN_BOOK_NAME = "bookName"
private const val COLUMN_BOOK_SHORT_NAME = "bookShortName"

@WorkerThread
fun createTable(db: SQLiteDatabase) {
db.execSQL("CREATE TABLE $TABLE_BOOK_NAMES (" +
"$COLUMN_TRANSLATION_SHORT_NAME TEXT NOT NULL, " +
"$COLUMN_BOOK_INDEX INTEGER NOT NULL, " +
"$COLUMN_BOOK_NAME TEXT NOT NULL, " +
"$COLUMN_BOOK_SHORT_NAME TEXT NOT NULL, " +
"PRIMARY KEY ($COLUMN_TRANSLATION_SHORT_NAME, $COLUMN_BOOK_INDEX));")
db.execSQL("CREATE INDEX $INDEX_BOOK_NAMES ON $TABLE_BOOK_NAMES ($COLUMN_TRANSLATION_SHORT_NAME);")
}
Expand All @@ -62,6 +64,23 @@ class BookNamesDao(private val sqliteHelper: SQLiteOpenHelper) {
}
}

@WorkerThread
fun readShortName(translationShortName: String): List<String> {
var cursor: Cursor? = null
try {
cursor = db.query(TABLE_BOOK_NAMES, arrayOf(COLUMN_BOOK_SHORT_NAME),
"$COLUMN_TRANSLATION_SHORT_NAME = ?", arrayOf(translationShortName), null, null,
"$COLUMN_BOOK_INDEX ASC")
val bookNames = ArrayList<String>(Bible.BOOK_COUNT)
while (cursor.moveToNext()) {
bookNames.add(cursor.getString(0))
}
return bookNames
} finally {
cursor?.close()
}
}

@WorkerThread
fun read(translations: List<String>, bookIndex: Int): Map<String, String> {
if (translations.isEmpty() || bookIndex < 0 || bookIndex >= Bible.BOOK_COUNT) {
Expand Down Expand Up @@ -127,12 +146,13 @@ class BookNamesDao(private val sqliteHelper: SQLiteOpenHelper) {
}

@WorkerThread
fun save(translationShortName: String, bookNames: List<String>) {
fun save(translationShortName: String, bookNames: List<String>, bookShortNames: List<String>) {
val values = ContentValues(3)
values.put(COLUMN_TRANSLATION_SHORT_NAME, translationShortName)
for ((bookIndex, bookName) in bookNames.withIndex()) {
values.put(COLUMN_BOOK_INDEX, bookIndex)
values.put(COLUMN_BOOK_NAME, bookName)
values.put(COLUMN_BOOK_SHORT_NAME, bookShortNames[bookIndex])
db.insertWithOnConflict(TABLE_BOOK_NAMES, null, values, SQLiteDatabase.CONFLICT_REPLACE)
}
}
Expand Down
Loading

0 comments on commit 7d15059

Please sign in to comment.