Optimize external plugin cursor
This commit is contained in:
@@ -16,8 +16,8 @@ android {
|
|||||||
applicationId 'org.koitharu.kotatsu'
|
applicationId 'org.koitharu.kotatsu'
|
||||||
minSdk = 21
|
minSdk = 21
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 657
|
versionCode = 658
|
||||||
versionName = '7.4'
|
versionName = '7.4.1'
|
||||||
generatedDensities = []
|
generatedDensities = []
|
||||||
testInstrumentationRunner 'org.koitharu.kotatsu.HiltTestRunner'
|
testInstrumentationRunner 'org.koitharu.kotatsu.HiltTestRunner'
|
||||||
ksp {
|
ksp {
|
||||||
@@ -82,7 +82,7 @@ afterEvaluate {
|
|||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
//noinspection GradleDependency
|
//noinspection GradleDependency
|
||||||
implementation('com.github.KotatsuApp:kotatsu-parsers:a9fc534ea7') {
|
implementation('com.github.KotatsuApp:kotatsu-parsers:853c21e49f') {
|
||||||
exclude group: 'org.json', module: 'json'
|
exclude group: 'org.json', module: 'json'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class ExternalPluginContentSource(
|
|||||||
null -> Unit
|
null -> Unit
|
||||||
}
|
}
|
||||||
contentResolver.query(uri.build(), null, null, null, filter?.sortOrder?.name)
|
contentResolver.query(uri.build(), null, null, null, filter?.sortOrder?.name)
|
||||||
.indexed()
|
.safe()
|
||||||
.use { cursor ->
|
.use { cursor ->
|
||||||
val result = ArrayList<Manga>(cursor.count)
|
val result = ArrayList<Manga>(cursor.count)
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
@@ -94,7 +94,7 @@ class ExternalPluginContentSource(
|
|||||||
.appendPath(chapter.url)
|
.appendPath(chapter.url)
|
||||||
.build()
|
.build()
|
||||||
contentResolver.query(uri, null, null, null, null)
|
contentResolver.query(uri, null, null, null, null)
|
||||||
.indexed()
|
.safe()
|
||||||
.use { cursor ->
|
.use { cursor ->
|
||||||
val result = ArrayList<MangaPage>(cursor.count)
|
val result = ArrayList<MangaPage>(cursor.count)
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
@@ -116,7 +116,7 @@ class ExternalPluginContentSource(
|
|||||||
fun getTags(): Set<MangaTag> = runCatchingCompatibility {
|
fun getTags(): Set<MangaTag> = runCatchingCompatibility {
|
||||||
val uri = "content://${source.authority}/tags".toUri()
|
val uri = "content://${source.authority}/tags".toUri()
|
||||||
contentResolver.query(uri, null, null, null, null)
|
contentResolver.query(uri, null, null, null, null)
|
||||||
.indexed()
|
.safe()
|
||||||
.use { cursor ->
|
.use { cursor ->
|
||||||
val result = ArraySet<MangaTag>(cursor.count)
|
val result = ArraySet<MangaTag>(cursor.count)
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
@@ -135,7 +135,7 @@ class ExternalPluginContentSource(
|
|||||||
fun getCapabilities(): MangaSourceCapabilities? {
|
fun getCapabilities(): MangaSourceCapabilities? {
|
||||||
val uri = "content://${source.authority}/capabilities".toUri()
|
val uri = "content://${source.authority}/capabilities".toUri()
|
||||||
return contentResolver.query(uri, null, null, null, null)
|
return contentResolver.query(uri, null, null, null, null)
|
||||||
.indexed()
|
.safe()
|
||||||
.use { cursor ->
|
.use { cursor ->
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
MangaSourceCapabilities(
|
MangaSourceCapabilities(
|
||||||
@@ -177,7 +177,7 @@ class ExternalPluginContentSource(
|
|||||||
.appendPath(url)
|
.appendPath(url)
|
||||||
.build()
|
.build()
|
||||||
return contentResolver.query(uri, null, null, null, null)
|
return contentResolver.query(uri, null, null, null, null)
|
||||||
.indexed()
|
.safe()
|
||||||
.use { cursor ->
|
.use { cursor ->
|
||||||
cursor.moveToFirst()
|
cursor.moveToFirst()
|
||||||
cursor.getManga()
|
cursor.getManga()
|
||||||
@@ -190,7 +190,7 @@ class ExternalPluginContentSource(
|
|||||||
.appendPath(url)
|
.appendPath(url)
|
||||||
.build()
|
.build()
|
||||||
return contentResolver.query(uri, null, null, null, null)
|
return contentResolver.query(uri, null, null, null, null)
|
||||||
.indexed()
|
.safe()
|
||||||
.use { cursor ->
|
.use { cursor ->
|
||||||
val result = ArrayList<MangaChapter>(cursor.count)
|
val result = ArrayList<MangaChapter>(cursor.count)
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
@@ -212,7 +212,7 @@ class ExternalPluginContentSource(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IndexedCursor.getManga() = Manga(
|
private fun SafeCursor.getManga() = Manga(
|
||||||
id = getLong(COLUMN_ID),
|
id = getLong(COLUMN_ID),
|
||||||
title = getString(COLUMN_TITLE),
|
title = getString(COLUMN_TITLE),
|
||||||
altTitle = getStringOrNull(COLUMN_ALT_TITLE),
|
altTitle = getStringOrNull(COLUMN_ALT_TITLE),
|
||||||
@@ -241,7 +241,7 @@ class ExternalPluginContentSource(
|
|||||||
throw IncompatiblePluginException(source.name, e)
|
throw IncompatiblePluginException(source.name, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Cursor?.indexed() = IndexedCursor(this ?: throw IncompatiblePluginException(source.name, null))
|
private fun Cursor?.safe() = SafeCursor(this ?: throw IncompatiblePluginException(source.name, null))
|
||||||
|
|
||||||
class MangaSourceCapabilities(
|
class MangaSourceCapabilities(
|
||||||
val availableSortOrders: Set<SortOrder>,
|
val availableSortOrders: Set<SortOrder>,
|
||||||
|
|||||||
@@ -2,77 +2,70 @@ package org.koitharu.kotatsu.core.parser.external
|
|||||||
|
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
import android.database.CursorWrapper
|
import android.database.CursorWrapper
|
||||||
import androidx.collection.MutableObjectIntMap
|
|
||||||
import androidx.collection.ObjectIntMap
|
|
||||||
import org.koitharu.kotatsu.core.util.ext.getBoolean
|
import org.koitharu.kotatsu.core.util.ext.getBoolean
|
||||||
|
|
||||||
class IndexedCursor(cursor: Cursor) : CursorWrapper(cursor) {
|
class SafeCursor(cursor: Cursor) : CursorWrapper(cursor) {
|
||||||
|
|
||||||
private val columns: ObjectIntMap<String> = MutableObjectIntMap<String>(columnCount).also { result ->
|
|
||||||
val names = columnNames
|
|
||||||
names.forEachIndexed { index, s -> result.put(s, index) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getString(columnName: String): String {
|
fun getString(columnName: String): String {
|
||||||
return getString(columns[columnName])
|
return getString(getColumnIndexOrThrow(columnName))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getStringOrNull(columnName: String): String? {
|
fun getStringOrNull(columnName: String): String? {
|
||||||
val columnIndex = columns.getOrDefault(columnName, -1)
|
val columnIndex = getColumnIndex(columnName)
|
||||||
return when {
|
return when {
|
||||||
columnIndex == -1 -> null
|
columnIndex < 0 -> null
|
||||||
isNull(columnIndex) -> null
|
isNull(columnIndex) -> null
|
||||||
else -> getString(columnIndex)
|
else -> getString(columnIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getBoolean(columnName: String): Boolean {
|
fun getBoolean(columnName: String): Boolean {
|
||||||
return getBoolean(columns[columnName])
|
return getBoolean(getColumnIndexOrThrow(columnName))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getBooleanOrDefault(columnName: String, defaultValue: Boolean): Boolean {
|
fun getBooleanOrDefault(columnName: String, defaultValue: Boolean): Boolean {
|
||||||
val columnIndex = columns.getOrDefault(columnName, -1)
|
val columnIndex = getColumnIndex(columnName)
|
||||||
return when {
|
return when {
|
||||||
columnIndex == -1 -> defaultValue
|
columnIndex < 0 -> defaultValue
|
||||||
isNull(columnIndex) -> defaultValue
|
isNull(columnIndex) -> defaultValue
|
||||||
else -> getBoolean(columnIndex)
|
else -> getBoolean(columnIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getInt(columnName: String): Int {
|
fun getInt(columnName: String): Int {
|
||||||
return getInt(columns[columnName])
|
return getInt(getColumnIndexOrThrow(columnName))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getIntOrDefault(columnName: String, defaultValue: Int): Int {
|
fun getIntOrDefault(columnName: String, defaultValue: Int): Int {
|
||||||
val columnIndex = columns.getOrDefault(columnName, -1)
|
val columnIndex = getColumnIndex(columnName)
|
||||||
return when {
|
return when {
|
||||||
columnIndex == -1 -> defaultValue
|
columnIndex < 0 -> defaultValue
|
||||||
isNull(columnIndex) -> defaultValue
|
isNull(columnIndex) -> defaultValue
|
||||||
else -> getInt(columnIndex)
|
else -> getInt(columnIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLong(columnName: String): Long {
|
fun getLong(columnName: String): Long {
|
||||||
return getLong(columns[columnName])
|
return getLong(getColumnIndexOrThrow(columnName))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLongOrDefault(columnName: String, defaultValue: Long): Long {
|
fun getLongOrDefault(columnName: String, defaultValue: Long): Long {
|
||||||
val columnIndex = columns.getOrDefault(columnName, -1)
|
val columnIndex = getColumnIndex(columnName)
|
||||||
return when {
|
return when {
|
||||||
columnIndex == -1 -> defaultValue
|
columnIndex < 0 -> defaultValue
|
||||||
isNull(columnIndex) -> defaultValue
|
isNull(columnIndex) -> defaultValue
|
||||||
else -> getLong(columnIndex)
|
else -> getLong(columnIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFloat(columnName: String): Float {
|
fun getFloat(columnName: String): Float {
|
||||||
return getFloat(columns[columnName])
|
return getFloat(getColumnIndexOrThrow(columnName))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFloatOrDefault(columnName: String, defaultValue: Float): Float {
|
fun getFloatOrDefault(columnName: String, defaultValue: Float): Float {
|
||||||
val columnIndex = columns.getOrDefault(columnName, -1)
|
val columnIndex = getColumnIndex(columnName)
|
||||||
return when {
|
return when {
|
||||||
columnIndex == -1 -> defaultValue
|
columnIndex < 0 -> defaultValue
|
||||||
isNull(columnIndex) -> defaultValue
|
isNull(columnIndex) -> defaultValue
|
||||||
else -> getFloat(columnIndex)
|
else -> getFloat(columnIndex)
|
||||||
}
|
}
|
||||||
@@ -31,5 +31,7 @@ data class ReadingProgress(
|
|||||||
CHAPTERS_LEFT -> totalChapters > 0 && percent in 0f..1f
|
CHAPTERS_LEFT -> totalChapters > 0 && percent in 0f..1f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isComplete() = percent >= 1f - Math.ulp(percent)
|
||||||
|
|
||||||
fun isReversed() = mode == PERCENT_LEFT || mode == CHAPTERS_LEFT
|
fun isReversed() = mode == PERCENT_LEFT || mode == CHAPTERS_LEFT
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user