This commit is contained in:
Horis
2025-07-14 15:22:35 +08:00
parent 2f59065228
commit 577b3bee35
12 changed files with 157 additions and 127 deletions
@@ -24,9 +24,9 @@ object DatabaseMigrations {
} }
private val migration_10_11 = object : Migration(10, 11) { private val migration_10_11 = object : Migration(10, 11) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE txtTocRules") db.execSQL("DROP TABLE txtTocRules")
database.execSQL( db.execSQL(
"""CREATE TABLE txtTocRules(id INTEGER NOT NULL, """CREATE TABLE txtTocRules(id INTEGER NOT NULL,
name TEXT NOT NULL, rule TEXT NOT NULL, serialNumber INTEGER NOT NULL, name TEXT NOT NULL, rule TEXT NOT NULL, serialNumber INTEGER NOT NULL,
enable INTEGER NOT NULL, PRIMARY KEY (id))""" enable INTEGER NOT NULL, PRIMARY KEY (id))"""
@@ -35,20 +35,20 @@ object DatabaseMigrations {
} }
private val migration_11_12 = object : Migration(11, 12) { private val migration_11_12 = object : Migration(11, 12) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE rssSources ADD style TEXT ") db.execSQL("ALTER TABLE rssSources ADD style TEXT ")
} }
} }
private val migration_12_13 = object : Migration(12, 13) { private val migration_12_13 = object : Migration(12, 13) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE rssSources ADD articleStyle INTEGER NOT NULL DEFAULT 0 ") db.execSQL("ALTER TABLE rssSources ADD articleStyle INTEGER NOT NULL DEFAULT 0 ")
} }
} }
private val migration_13_14 = object : Migration(13, 14) { private val migration_13_14 = object : Migration(13, 14) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL( db.execSQL(
"""CREATE TABLE IF NOT EXISTS `books_new` (`bookUrl` TEXT NOT NULL, `tocUrl` TEXT NOT NULL, `origin` TEXT NOT NULL, """CREATE TABLE IF NOT EXISTS `books_new` (`bookUrl` TEXT NOT NULL, `tocUrl` TEXT NOT NULL, `origin` TEXT NOT NULL,
`originName` TEXT NOT NULL, `name` TEXT NOT NULL, `author` TEXT NOT NULL, `kind` TEXT, `customTag` TEXT, `coverUrl` TEXT, `originName` TEXT NOT NULL, `name` TEXT NOT NULL, `author` TEXT NOT NULL, `kind` TEXT, `customTag` TEXT, `coverUrl` TEXT,
`customCoverUrl` TEXT, `intro` TEXT, `customIntro` TEXT, `charset` TEXT, `type` INTEGER NOT NULL, `group` INTEGER NOT NULL, `customCoverUrl` TEXT, `intro` TEXT, `customIntro` TEXT, `charset` TEXT, `type` INTEGER NOT NULL, `group` INTEGER NOT NULL,
@@ -57,57 +57,57 @@ object DatabaseMigrations {
`durChapterTime` INTEGER NOT NULL, `wordCount` TEXT, `canUpdate` INTEGER NOT NULL, `order` INTEGER NOT NULL, `durChapterTime` INTEGER NOT NULL, `wordCount` TEXT, `canUpdate` INTEGER NOT NULL, `order` INTEGER NOT NULL,
`originOrder` INTEGER NOT NULL, `useReplaceRule` INTEGER NOT NULL, `variable` TEXT, PRIMARY KEY(`bookUrl`))""" `originOrder` INTEGER NOT NULL, `useReplaceRule` INTEGER NOT NULL, `variable` TEXT, PRIMARY KEY(`bookUrl`))"""
) )
database.execSQL("INSERT INTO books_new select * from books ") db.execSQL("INSERT INTO books_new select * from books ")
database.execSQL("DROP TABLE books") db.execSQL("DROP TABLE books")
database.execSQL("ALTER TABLE books_new RENAME TO books") db.execSQL("ALTER TABLE books_new RENAME TO books")
database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_books_name_author` ON `books` (`name`, `author`) ") db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_books_name_author` ON `books` (`name`, `author`) ")
} }
} }
private val migration_14_15 = object : Migration(14, 15) { private val migration_14_15 = object : Migration(14, 15) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE bookmarks ADD bookAuthor TEXT NOT NULL DEFAULT ''") db.execSQL("ALTER TABLE bookmarks ADD bookAuthor TEXT NOT NULL DEFAULT ''")
} }
} }
private val migration_15_17 = object : Migration(15, 17) { private val migration_15_17 = object : Migration(15, 17) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `readRecord` (`bookName` TEXT NOT NULL, `readTime` INTEGER NOT NULL, PRIMARY KEY(`bookName`))") db.execSQL("CREATE TABLE IF NOT EXISTS `readRecord` (`bookName` TEXT NOT NULL, `readTime` INTEGER NOT NULL, PRIMARY KEY(`bookName`))")
} }
} }
private val migration_17_18 = object : Migration(17, 18) { private val migration_17_18 = object : Migration(17, 18) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `httpTTS` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `url` TEXT NOT NULL, PRIMARY KEY(`id`))") db.execSQL("CREATE TABLE IF NOT EXISTS `httpTTS` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `url` TEXT NOT NULL, PRIMARY KEY(`id`))")
} }
} }
private val migration_18_19 = object : Migration(18, 19) { private val migration_18_19 = object : Migration(18, 19) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL( db.execSQL(
"""CREATE TABLE IF NOT EXISTS `readRecordNew` (`androidId` TEXT NOT NULL, `bookName` TEXT NOT NULL, `readTime` INTEGER NOT NULL, """CREATE TABLE IF NOT EXISTS `readRecordNew` (`androidId` TEXT NOT NULL, `bookName` TEXT NOT NULL, `readTime` INTEGER NOT NULL,
PRIMARY KEY(`androidId`, `bookName`))""" PRIMARY KEY(`androidId`, `bookName`))"""
) )
database.execSQL("INSERT INTO readRecordNew(androidId, bookName, readTime) select '${AppConst.androidId}' as androidId, bookName, readTime from readRecord") db.execSQL("INSERT INTO readRecordNew(androidId, bookName, readTime) select '${AppConst.androidId}' as androidId, bookName, readTime from readRecord")
database.execSQL("DROP TABLE readRecord") db.execSQL("DROP TABLE readRecord")
database.execSQL("ALTER TABLE readRecordNew RENAME TO readRecord") db.execSQL("ALTER TABLE readRecordNew RENAME TO readRecord")
} }
} }
private val migration_19_20 = object : Migration(19, 20) { private val migration_19_20 = object : Migration(19, 20) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE book_sources ADD bookSourceComment TEXT") db.execSQL("ALTER TABLE book_sources ADD bookSourceComment TEXT")
} }
} }
private val migration_20_21 = object : Migration(20, 21) { private val migration_20_21 = object : Migration(20, 21) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE book_groups ADD show INTEGER NOT NULL DEFAULT 1") db.execSQL("ALTER TABLE book_groups ADD show INTEGER NOT NULL DEFAULT 1")
} }
} }
private val migration_21_22 = object : Migration(21, 22) { private val migration_21_22 = object : Migration(21, 22) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL( db.execSQL(
"""CREATE TABLE IF NOT EXISTS `books_new` (`bookUrl` TEXT NOT NULL, `tocUrl` TEXT NOT NULL, `origin` TEXT NOT NULL, """CREATE TABLE IF NOT EXISTS `books_new` (`bookUrl` TEXT NOT NULL, `tocUrl` TEXT NOT NULL, `origin` TEXT NOT NULL,
`originName` TEXT NOT NULL, `name` TEXT NOT NULL, `author` TEXT NOT NULL, `kind` TEXT, `customTag` TEXT, `originName` TEXT NOT NULL, `name` TEXT NOT NULL, `author` TEXT NOT NULL, `kind` TEXT, `customTag` TEXT,
`coverUrl` TEXT, `customCoverUrl` TEXT, `intro` TEXT, `customIntro` TEXT, `charset` TEXT, `type` INTEGER NOT NULL, `coverUrl` TEXT, `customCoverUrl` TEXT, `intro` TEXT, `customIntro` TEXT, `charset` TEXT, `type` INTEGER NOT NULL,
@@ -116,35 +116,35 @@ object DatabaseMigrations {
`durChapterPos` INTEGER NOT NULL, `durChapterTime` INTEGER NOT NULL, `wordCount` TEXT, `canUpdate` INTEGER NOT NULL, `durChapterPos` INTEGER NOT NULL, `durChapterTime` INTEGER NOT NULL, `wordCount` TEXT, `canUpdate` INTEGER NOT NULL,
`order` INTEGER NOT NULL, `originOrder` INTEGER NOT NULL, `variable` TEXT, `readConfig` TEXT, PRIMARY KEY(`bookUrl`))""" `order` INTEGER NOT NULL, `originOrder` INTEGER NOT NULL, `variable` TEXT, `readConfig` TEXT, PRIMARY KEY(`bookUrl`))"""
) )
database.execSQL( db.execSQL(
"""INSERT INTO books_new select `bookUrl`, `tocUrl`, `origin`, `originName`, `name`, `author`, `kind`, `customTag`, `coverUrl`, """INSERT INTO books_new select `bookUrl`, `tocUrl`, `origin`, `originName`, `name`, `author`, `kind`, `customTag`, `coverUrl`,
`customCoverUrl`, `intro`, `customIntro`, `charset`, `type`, `group`, `latestChapterTitle`, `latestChapterTime`, `lastCheckTime`, `customCoverUrl`, `intro`, `customIntro`, `charset`, `type`, `group`, `latestChapterTitle`, `latestChapterTime`, `lastCheckTime`,
`lastCheckCount`, `totalChapterNum`, `durChapterTitle`, `durChapterIndex`, `durChapterPos`, `durChapterTime`, `wordCount`, `canUpdate`, `lastCheckCount`, `totalChapterNum`, `durChapterTitle`, `durChapterIndex`, `durChapterPos`, `durChapterTime`, `wordCount`, `canUpdate`,
`order`, `originOrder`, `variable`, null `order`, `originOrder`, `variable`, null
from books""" from books"""
) )
database.execSQL("DROP TABLE books") db.execSQL("DROP TABLE books")
database.execSQL("ALTER TABLE books_new RENAME TO books") db.execSQL("ALTER TABLE books_new RENAME TO books")
database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_books_name_author` ON `books` (`name`, `author`) ") db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_books_name_author` ON `books` (`name`, `author`) ")
} }
} }
private val migration_22_23 = object : Migration(22, 23) { private val migration_22_23 = object : Migration(22, 23) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE chapters ADD baseUrl TEXT NOT NULL DEFAULT ''") db.execSQL("ALTER TABLE chapters ADD baseUrl TEXT NOT NULL DEFAULT ''")
} }
} }
private val migration_23_24 = object : Migration(23, 24) { private val migration_23_24 = object : Migration(23, 24) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `caches` (`key` TEXT NOT NULL, `value` TEXT, `deadline` INTEGER NOT NULL, PRIMARY KEY(`key`))") db.execSQL("CREATE TABLE IF NOT EXISTS `caches` (`key` TEXT NOT NULL, `value` TEXT, `deadline` INTEGER NOT NULL, PRIMARY KEY(`key`))")
database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_caches_key` ON `caches` (`key`)") db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_caches_key` ON `caches` (`key`)")
} }
} }
private val migration_24_25 = object : Migration(24, 25) { private val migration_24_25 = object : Migration(24, 25) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL( db.execSQL(
"""CREATE TABLE IF NOT EXISTS `sourceSubs` """CREATE TABLE IF NOT EXISTS `sourceSubs`
(`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `url` TEXT NOT NULL, `type` INTEGER NOT NULL, `customOrder` INTEGER NOT NULL, (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `url` TEXT NOT NULL, `type` INTEGER NOT NULL, `customOrder` INTEGER NOT NULL,
PRIMARY KEY(`id`))""" PRIMARY KEY(`id`))"""
@@ -153,86 +153,86 @@ object DatabaseMigrations {
} }
private val migration_25_26 = object : Migration(25, 26) { private val migration_25_26 = object : Migration(25, 26) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL( db.execSQL(
"""CREATE TABLE IF NOT EXISTS `ruleSubs` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `url` TEXT NOT NULL, `type` INTEGER NOT NULL, """CREATE TABLE IF NOT EXISTS `ruleSubs` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `url` TEXT NOT NULL, `type` INTEGER NOT NULL,
`customOrder` INTEGER NOT NULL, `autoUpdate` INTEGER NOT NULL, `update` INTEGER NOT NULL, PRIMARY KEY(`id`))""" `customOrder` INTEGER NOT NULL, `autoUpdate` INTEGER NOT NULL, `update` INTEGER NOT NULL, PRIMARY KEY(`id`))"""
) )
database.execSQL(" insert into `ruleSubs` select *, 0, 0 from `sourceSubs` ") db.execSQL(" insert into `ruleSubs` select *, 0, 0 from `sourceSubs` ")
database.execSQL("DROP TABLE `sourceSubs`") db.execSQL("DROP TABLE `sourceSubs`")
} }
} }
private val migration_26_27 = object : Migration(26, 27) { private val migration_26_27 = object : Migration(26, 27) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL(" ALTER TABLE rssSources ADD singleUrl INTEGER NOT NULL DEFAULT 0 ") db.execSQL(" ALTER TABLE rssSources ADD singleUrl INTEGER NOT NULL DEFAULT 0 ")
database.execSQL( db.execSQL(
"""CREATE TABLE IF NOT EXISTS `bookmarks1` (`time` INTEGER NOT NULL, `bookUrl` TEXT NOT NULL, `bookName` TEXT NOT NULL, """CREATE TABLE IF NOT EXISTS `bookmarks1` (`time` INTEGER NOT NULL, `bookUrl` TEXT NOT NULL, `bookName` TEXT NOT NULL,
`bookAuthor` TEXT NOT NULL, `chapterIndex` INTEGER NOT NULL, `chapterPos` INTEGER NOT NULL, `chapterName` TEXT NOT NULL, `bookAuthor` TEXT NOT NULL, `chapterIndex` INTEGER NOT NULL, `chapterPos` INTEGER NOT NULL, `chapterName` TEXT NOT NULL,
`bookText` TEXT NOT NULL, `content` TEXT NOT NULL, PRIMARY KEY(`time`))""" `bookText` TEXT NOT NULL, `content` TEXT NOT NULL, PRIMARY KEY(`time`))"""
) )
database.execSQL( db.execSQL(
"""insert into `bookmarks1` """insert into `bookmarks1`
select `time`, `bookUrl`, `bookName`, `bookAuthor`, `chapterIndex`, `pageIndex`, `chapterName`, '', `content` select `time`, `bookUrl`, `bookName`, `bookAuthor`, `chapterIndex`, `pageIndex`, `chapterName`, '', `content`
from bookmarks""" from bookmarks"""
) )
database.execSQL(" DROP TABLE `bookmarks` ") db.execSQL(" DROP TABLE `bookmarks` ")
database.execSQL(" ALTER TABLE bookmarks1 RENAME TO bookmarks ") db.execSQL(" ALTER TABLE bookmarks1 RENAME TO bookmarks ")
database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_bookmarks_time` ON `bookmarks` (`time`)") db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_bookmarks_time` ON `bookmarks` (`time`)")
} }
} }
private val migration_27_28 = object : Migration(27, 28) { private val migration_27_28 = object : Migration(27, 28) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE rssArticles ADD variable TEXT") db.execSQL("ALTER TABLE rssArticles ADD variable TEXT")
database.execSQL("ALTER TABLE rssStars ADD variable TEXT") db.execSQL("ALTER TABLE rssStars ADD variable TEXT")
} }
} }
private val migration_28_29 = object : Migration(28, 29) { private val migration_28_29 = object : Migration(28, 29) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE rssSources ADD sourceComment TEXT") db.execSQL("ALTER TABLE rssSources ADD sourceComment TEXT")
} }
} }
private val migration_29_30 = object : Migration(29, 30) { private val migration_29_30 = object : Migration(29, 30) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE chapters ADD `startFragmentId` TEXT") db.execSQL("ALTER TABLE chapters ADD `startFragmentId` TEXT")
database.execSQL("ALTER TABLE chapters ADD `endFragmentId` TEXT") db.execSQL("ALTER TABLE chapters ADD `endFragmentId` TEXT")
database.execSQL( db.execSQL(
""" """
CREATE TABLE IF NOT EXISTS `epubChapters` CREATE TABLE IF NOT EXISTS `epubChapters`
(`bookUrl` TEXT NOT NULL, `href` TEXT NOT NULL, `parentHref` TEXT, (`bookUrl` TEXT NOT NULL, `href` TEXT NOT NULL, `parentHref` TEXT,
PRIMARY KEY(`bookUrl`, `href`), FOREIGN KEY(`bookUrl`) REFERENCES `books`(`bookUrl`) ON UPDATE NO ACTION ON DELETE CASCADE ) PRIMARY KEY(`bookUrl`, `href`), FOREIGN KEY(`bookUrl`) REFERENCES `books`(`bookUrl`) ON UPDATE NO ACTION ON DELETE CASCADE )
""" """
) )
database.execSQL("CREATE INDEX IF NOT EXISTS `index_epubChapters_bookUrl` ON `epubChapters` (`bookUrl`)") db.execSQL("CREATE INDEX IF NOT EXISTS `index_epubChapters_bookUrl` ON `epubChapters` (`bookUrl`)")
database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_epubChapters_bookUrl_href` ON `epubChapters` (`bookUrl`, `href`)") db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_epubChapters_bookUrl_href` ON `epubChapters` (`bookUrl`, `href`)")
} }
} }
private val migration_30_31 = object : Migration(30, 31) { private val migration_30_31 = object : Migration(30, 31) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE readRecord RENAME TO readRecord1") db.execSQL("ALTER TABLE readRecord RENAME TO readRecord1")
database.execSQL( db.execSQL(
""" """
CREATE TABLE IF NOT EXISTS `readRecord` (`deviceId` TEXT NOT NULL, `bookName` TEXT NOT NULL, `readTime` INTEGER NOT NULL, PRIMARY KEY(`deviceId`, `bookName`)) CREATE TABLE IF NOT EXISTS `readRecord` (`deviceId` TEXT NOT NULL, `bookName` TEXT NOT NULL, `readTime` INTEGER NOT NULL, PRIMARY KEY(`deviceId`, `bookName`))
""" """
) )
database.execSQL("insert into readRecord (deviceId, bookName, readTime) select androidId, bookName, readTime from readRecord1") db.execSQL("insert into readRecord (deviceId, bookName, readTime) select androidId, bookName, readTime from readRecord1")
} }
} }
private val migration_31_32 = object : Migration(31, 32) { private val migration_31_32 = object : Migration(31, 32) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE `epubChapters`") db.execSQL("DROP TABLE `epubChapters`")
} }
} }
private val migration_32_33 = object : Migration(32, 33) { private val migration_32_33 = object : Migration(32, 33) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE bookmarks RENAME TO bookmarks_old") db.execSQL("ALTER TABLE bookmarks RENAME TO bookmarks_old")
database.execSQL( db.execSQL(
""" """
CREATE TABLE IF NOT EXISTS `bookmarks` (`time` INTEGER NOT NULL, CREATE TABLE IF NOT EXISTS `bookmarks` (`time` INTEGER NOT NULL,
`bookName` TEXT NOT NULL, `bookAuthor` TEXT NOT NULL, `chapterIndex` INTEGER NOT NULL, `bookName` TEXT NOT NULL, `bookAuthor` TEXT NOT NULL, `chapterIndex` INTEGER NOT NULL,
@@ -240,12 +240,12 @@ object DatabaseMigrations {
`content` TEXT NOT NULL, PRIMARY KEY(`time`)) `content` TEXT NOT NULL, PRIMARY KEY(`time`))
""" """
) )
database.execSQL( db.execSQL(
""" """
CREATE INDEX IF NOT EXISTS `index_bookmarks_bookName_bookAuthor` ON `bookmarks` (`bookName`, `bookAuthor`) CREATE INDEX IF NOT EXISTS `index_bookmarks_bookName_bookAuthor` ON `bookmarks` (`bookName`, `bookAuthor`)
""" """
) )
database.execSQL( db.execSQL(
""" """
insert into bookmarks (time, bookName, bookAuthor, chapterIndex, chapterPos, chapterName, bookText, content) insert into bookmarks (time, bookName, bookAuthor, chapterIndex, chapterPos, chapterName, bookText, content)
select time, ifNull(b.name, bookName) bookName, ifNull(b.author, bookAuthor) bookAuthor, select time, ifNull(b.name, bookName) bookName, ifNull(b.author, bookAuthor) bookAuthor,
@@ -257,70 +257,70 @@ object DatabaseMigrations {
} }
private val migration_33_34 = object : Migration(33, 34) { private val migration_33_34 = object : Migration(33, 34) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE `book_groups` ADD `cover` TEXT") db.execSQL("ALTER TABLE `book_groups` ADD `cover` TEXT")
} }
} }
private val migration_34_35 = object : Migration(34, 35) { private val migration_34_35 = object : Migration(34, 35) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE `book_sources` ADD `concurrentRate` TEXT") db.execSQL("ALTER TABLE `book_sources` ADD `concurrentRate` TEXT")
} }
} }
private val migration_35_36 = object : Migration(35, 36) { private val migration_35_36 = object : Migration(35, 36) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE `book_sources` ADD `loginUi` TEXT") db.execSQL("ALTER TABLE `book_sources` ADD `loginUi` TEXT")
database.execSQL("ALTER TABLE `book_sources` ADD`loginCheckJs` TEXT") db.execSQL("ALTER TABLE `book_sources` ADD`loginCheckJs` TEXT")
} }
} }
private val migration_36_37 = object : Migration(36, 37) { private val migration_36_37 = object : Migration(36, 37) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE `rssSources` ADD `loginUrl` TEXT") db.execSQL("ALTER TABLE `rssSources` ADD `loginUrl` TEXT")
database.execSQL("ALTER TABLE `rssSources` ADD `loginUi` TEXT") db.execSQL("ALTER TABLE `rssSources` ADD `loginUi` TEXT")
database.execSQL("ALTER TABLE `rssSources` ADD `loginCheckJs` TEXT") db.execSQL("ALTER TABLE `rssSources` ADD `loginCheckJs` TEXT")
} }
} }
private val migration_37_38 = object : Migration(37, 38) { private val migration_37_38 = object : Migration(37, 38) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE `book_sources` ADD `respondTime` INTEGER NOT NULL DEFAULT 180000") db.execSQL("ALTER TABLE `book_sources` ADD `respondTime` INTEGER NOT NULL DEFAULT 180000")
} }
} }
private val migration_38_39 = object : Migration(38, 39) { private val migration_38_39 = object : Migration(38, 39) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE `rssSources` ADD `concurrentRate` TEXT") db.execSQL("ALTER TABLE `rssSources` ADD `concurrentRate` TEXT")
} }
} }
private val migration_39_40 = object : Migration(39, 40) { private val migration_39_40 = object : Migration(39, 40) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE `chapters` ADD `isVip` INTEGER NOT NULL DEFAULT 0") db.execSQL("ALTER TABLE `chapters` ADD `isVip` INTEGER NOT NULL DEFAULT 0")
database.execSQL("ALTER TABLE `chapters` ADD `isPay` INTEGER NOT NULL DEFAULT 0") db.execSQL("ALTER TABLE `chapters` ADD `isPay` INTEGER NOT NULL DEFAULT 0")
} }
} }
private val migration_40_41 = object : Migration(40, 41) { private val migration_40_41 = object : Migration(40, 41) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE `httpTTS` ADD `loginUrl` TEXT") db.execSQL("ALTER TABLE `httpTTS` ADD `loginUrl` TEXT")
database.execSQL("ALTER TABLE `httpTTS` ADD `loginUi` TEXT") db.execSQL("ALTER TABLE `httpTTS` ADD `loginUi` TEXT")
database.execSQL("ALTER TABLE `httpTTS` ADD `loginCheckJs` TEXT") db.execSQL("ALTER TABLE `httpTTS` ADD `loginCheckJs` TEXT")
database.execSQL("ALTER TABLE `httpTTS` ADD `header` TEXT") db.execSQL("ALTER TABLE `httpTTS` ADD `header` TEXT")
database.execSQL("ALTER TABLE `httpTTS` ADD `concurrentRate` TEXT") db.execSQL("ALTER TABLE `httpTTS` ADD `concurrentRate` TEXT")
} }
} }
private val migration_41_42 = object : Migration(41, 42) { private val migration_41_42 = object : Migration(41, 42) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE 'httpTTS' ADD `contentType` TEXT") db.execSQL("ALTER TABLE 'httpTTS' ADD `contentType` TEXT")
} }
} }
private val migration_42_43 = object : Migration(42, 43) { private val migration_42_43 = object : Migration(42, 43) {
override fun migrate(database: SupportSQLiteDatabase) { override fun migrate(db: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE `chapters` ADD `isVolume` INTEGER NOT NULL DEFAULT 0") db.execSQL("ALTER TABLE `chapters` ADD `isVolume` INTEGER NOT NULL DEFAULT 0")
} }
} }
@@ -12,7 +12,7 @@ import java.security.MessageDigest
* @radius: 0..25 * @radius: 0..25
*/ */
class BlurTransformation( class BlurTransformation(
@IntRange(from = 0, to = 25) private val radius: Int @param:IntRange(from = 0, to = 25) private val radius: Int
) : BitmapTransformation() { ) : BitmapTransformation() {
override fun transform( override fun transform(
@@ -2,6 +2,7 @@ package io.legado.app.help.http
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.Response import okhttp3.Response
import okhttp3.ResponseBody
import okhttp3.ResponseBody.Companion.asResponseBody import okhttp3.ResponseBody.Companion.asResponseBody
import okhttp3.internal.http.promisesBody import okhttp3.internal.http.promisesBody
import okio.buffer import okio.buffer
@@ -24,7 +25,7 @@ object DecompressInterceptor : Interceptor {
val response = chain.proceed(requestBuilder.build()) val response = chain.proceed(requestBuilder.build())
val body = response.body val body = response.body
if (!transparentDecompress || !response.promisesBody() || body == null) { if (!transparentDecompress || !response.promisesBody() || body == ResponseBody.EMPTY) {
return response return response
} }
@@ -127,7 +127,7 @@ val okHttpClientManga by lazy {
val response = chain.proceed(request) val response = chain.proceed(request)
val url = request.url.toString() val url = request.url.toString()
response.newBuilder() response.newBuilder()
.body(ProgressResponseBody(url, LISTENER, response.body!!)) .body(ProgressResponseBody(url, LISTENER, response.body))
.build() .build()
} }
interceptors.add(1) { chain -> interceptors.add(1) { chain ->
@@ -18,8 +18,6 @@ import okhttp3.Protocol
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
import okhttp3.Response import okhttp3.Response
import okhttp3.internal.notifyAll
import okhttp3.internal.wait
import okio.Buffer import okio.Buffer
import okio.BufferedSink import okio.BufferedSink
import okio.Pipe import okio.Pipe
@@ -186,7 +184,7 @@ class ObsoleteUrlFactory(private var client: OkHttpClient) : URLStreamHandlerFac
return try { return try {
val response = getResponse(true) val response = getResponse(true)
if (hasBody(response) && response.code >= HTTP_BAD_REQUEST) { if (hasBody(response) && response.code >= HTTP_BAD_REQUEST) {
response.body!!.byteStream() response.body.byteStream()
} else null } else null
} catch (e: IOException) { } catch (e: IOException) {
null null
@@ -258,7 +256,7 @@ class ObsoleteUrlFactory(private var client: OkHttpClient) : URLStreamHandlerFac
} }
val response = getResponse(false) val response = getResponse(false)
if (response.code >= HTTP_BAD_REQUEST) throw FileNotFoundException(url.toString()) if (response.code >= HTTP_BAD_REQUEST) throw FileNotFoundException(url.toString())
return response.body!!.byteStream() return response.body.byteStream()
} }
@Throws(IOException::class) @Throws(IOException::class)
@@ -1174,6 +1172,15 @@ class ObsoleteUrlFactory(private var client: OkHttpClient) : URLStreamHandlerFac
throw AssertionError() throw AssertionError()
} }
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "NOTHING_TO_INLINE")
private inline fun Any.wait() = (this as Object).wait()
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "NOTHING_TO_INLINE")
private inline fun Any.notify() = (this as Object).notify()
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "NOTHING_TO_INLINE")
private inline fun Any.notifyAll() = (this as Object).notifyAll()
@Throws(Exception::class) @Throws(Exception::class)
@JvmStatic @JvmStatic
fun main(args: Array<String>) { fun main(args: Array<String>) {
@@ -9,12 +9,19 @@ import io.legado.app.utils.DebugLog
import io.legado.app.utils.asIOException import io.legado.app.utils.asIOException
import io.legado.app.utils.splitNotBlank import io.legado.app.utils.splitNotBlank
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import okhttp3.* import okhttp3.Call
import okhttp3.Callback
import okhttp3.EventListener import okhttp3.EventListener
import okhttp3.Headers
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.Protocol
import okhttp3.Request
import okhttp3.Response
import okhttp3.ResponseBody
import okhttp3.ResponseBody.Companion.asResponseBody import okhttp3.ResponseBody.Companion.asResponseBody
import okhttp3.internal.http.HTTP_PERM_REDIRECT
import okhttp3.internal.http.HTTP_TEMP_REDIRECT
import okhttp3.internal.http.HttpMethod import okhttp3.internal.http.HttpMethod
import okhttp3.internal.http.StatusLine
import okio.Buffer import okio.Buffer
import okio.Source import okio.Source
import okio.Timeout import okio.Timeout
@@ -25,7 +32,7 @@ import org.chromium.net.UrlResponseInfo
import java.io.IOException import java.io.IOException
import java.net.ProtocolException import java.net.ProtocolException
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.util.* import java.util.Locale
import java.util.concurrent.ArrayBlockingQueue import java.util.concurrent.ArrayBlockingQueue
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
@@ -98,9 +105,15 @@ abstract class AbsCallBack(
followCount += 1 followCount += 1
urlResponseInfoChain.add(info) urlResponseInfoChain.add(info)
val client = okHttpClient val client = okHttpClient
if (originalRequest.url.isHttps && newLocationUrl.startsWith("http://") && client.followSslRedirects) { if (originalRequest.url.isHttps
&& newLocationUrl.startsWith("http://")
&& client.followSslRedirects
) {
followRedirect = true followRedirect = true
} else if (!originalRequest.url.isHttps && newLocationUrl.startsWith("https://") && client.followSslRedirects) { } else if (!originalRequest.url.isHttps
&& newLocationUrl.startsWith("https://")
&& client.followSslRedirects
) {
followRedirect = true followRedirect = true
} else if (okHttpClient.followRedirects) { } else if (okHttpClient.followRedirects) {
followRedirect = true followRedirect = true
@@ -315,7 +328,7 @@ abstract class AbsCallBack(
contentLength, contentLength,
bodySource bodySource
) )
} } ?: ResponseBody.EMPTY
return Response.Builder() return Response.Builder()
.request(request) .request(request)
@@ -381,9 +394,12 @@ abstract class AbsCallBack(
if (HttpMethod.permitsRequestBody(method)) { if (HttpMethod.permitsRequestBody(method)) {
val responseCode = userResponse.code val responseCode = userResponse.code
val maintainBody = HttpMethod.redirectsWithBody(method) || val maintainBody = HttpMethod.redirectsWithBody(method) ||
responseCode == StatusLine.HTTP_PERM_REDIRECT || responseCode == HTTP_PERM_REDIRECT ||
responseCode == StatusLine.HTTP_TEMP_REDIRECT responseCode == HTTP_TEMP_REDIRECT
if (HttpMethod.redirectsToGet(method) && responseCode != StatusLine.HTTP_PERM_REDIRECT && responseCode != StatusLine.HTTP_TEMP_REDIRECT) { if (HttpMethod.redirectsToGet(method)
&& responseCode != HTTP_PERM_REDIRECT
&& responseCode != HTTP_TEMP_REDIRECT
) {
requestBuilder.method("GET", null) requestBuilder.method("GET", null)
} else { } else {
val requestBody = if (maintainBody) userResponse.request.body else null val requestBody = if (maintainBody) userResponse.request.body else null
@@ -16,11 +16,11 @@ import io.legado.app.lib.mobi.entities.Ptagx
import io.legado.app.lib.mobi.entities.TOC import io.legado.app.lib.mobi.entities.TOC
import io.legado.app.lib.mobi.entities.TagxHeader import io.legado.app.lib.mobi.entities.TagxHeader
import io.legado.app.lib.mobi.entities.TagxTag import io.legado.app.lib.mobi.entities.TagxTag
import io.legado.app.lib.mobi.utils.and
import io.legado.app.lib.mobi.utils.readString import io.legado.app.lib.mobi.utils.readString
import io.legado.app.lib.mobi.utils.readUInt16Array import io.legado.app.lib.mobi.utils.readUInt16Array
import io.legado.app.lib.mobi.utils.readUInt32 import io.legado.app.lib.mobi.utils.readUInt32
import io.legado.app.lib.mobi.utils.readUInt8 import io.legado.app.lib.mobi.utils.readUInt8
import okhttp3.internal.and
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.InputStream import java.io.InputStream
import java.nio.ByteBuffer import java.nio.ByteBuffer
@@ -0,0 +1,7 @@
package io.legado.app.lib.mobi.utils
internal infix fun Byte.and(mask: Int): Int = toInt() and mask
internal infix fun Short.and(mask: Int): Int = toInt() and mask
internal infix fun Int.and(mask: Long): Long = toLong() and mask
@@ -1,6 +1,5 @@
package io.legado.app.lib.mobi.utils package io.legado.app.lib.mobi.utils
import okhttp3.internal.and
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.nio.charset.Charset import java.nio.charset.Charset
@@ -457,7 +457,7 @@ class AnalyzeUrl(
else -> get(urlNoQuery, encodedQuery) else -> get(urlNoQuery, encodedQuery)
} }
}.let { }.let {
val isXml = it.raw.body?.contentType()?.toString() val isXml = it.raw.body.contentType()?.toString()
?.matches(AppPattern.xmlContentTypeRegex) == true ?.matches(AppPattern.xmlContentTypeRegex) == true
if (isXml && it.body?.trim()?.startsWith("<?xml", true) == false) { if (isXml && it.body?.trim()?.startsWith("<?xml", true) == false) {
StrResponse(it.raw, "<?xml version=\"1.0\"?>" + it.body) StrResponse(it.raw, "<?xml version=\"1.0\"?>" + it.body)
@@ -552,7 +552,7 @@ class AnalyzeUrl(
getByteArrayIfDataUri()?.let { getByteArrayIfDataUri()?.let {
return it return it
} }
return getResponseAwait().body!!.bytes() return getResponseAwait().body.bytes()
} }
fun getByteArray(): ByteArray { fun getByteArray(): ByteArray {
@@ -568,7 +568,7 @@ class AnalyzeUrl(
getByteArrayIfDataUri()?.let { getByteArrayIfDataUri()?.let {
return ByteArrayInputStream(it) return ByteArrayInputStream(it)
} }
return getResponseAwait().body!!.byteStream() return getResponseAwait().body.byteStream()
} }
fun getInputStream(): InputStream { fun getInputStream(): InputStream {
@@ -343,17 +343,17 @@ class HttpReadAloudService : BaseReadAloudService(),
val contentType = contentType.substringBefore(";") val contentType = contentType.substringBefore(";")
val ct = httpTts.contentType val ct = httpTts.contentType
if (contentType == "application/json" || contentType.startsWith("text/")) { if (contentType == "application/json" || contentType.startsWith("text/")) {
throw NoStackTraceException(response.body!!.string()) throw NoStackTraceException(response.body.string())
} else if (ct?.isNotBlank() == true) { } else if (ct?.isNotBlank() == true) {
if (!contentType.matches(ct.toRegex())) { if (!contentType.matches(ct.toRegex())) {
throw NoStackTraceException( throw NoStackTraceException(
"TTS服务器返回错误:" + response.body!!.string() "TTS服务器返回错误:" + response.body.string()
) )
} }
} }
} }
coroutineContext.ensureActive() coroutineContext.ensureActive()
response.body!!.byteStream().let { stream -> response.body.byteStream().let { stream ->
downloadErrorNo = 0 downloadErrorNo = 0
return stream return stream
} }
+1 -1
View File
@@ -31,7 +31,7 @@ material = "1.12.0"
media = "1.7.0" media = "1.7.0"
media3 = "1.6.1" media3 = "1.6.1"
nanoHttpd = "2.3.1" nanoHttpd = "2.3.1"
okhttp = "4.12.0" okhttp = "5.1.0"
preference = "1.2.1" preference = "1.2.1"
protobufJavalite = "4.26.1" protobufJavalite = "4.26.1"
quickChineseTransfer = "0.2.16" quickChineseTransfer = "0.2.16"