From 1d9f5514ff964adb5ef1b3ecd710fd19744d272a Mon Sep 17 00:00:00 2001 From: Acclorite <2ma0bhpk@anonaddy.com> Date: Mon, 1 Sep 2025 22:18:49 +0300 Subject: [PATCH] refactor: book entity * Remove nullability from author --- .../15.json | 221 ++++++++++++++++++ .../acclorite/book_story/data/di/AppModule.kt | 1 + .../book_story/data/local/dto/BookEntity.kt | 2 +- .../data/local/room/BookDatabase.kt | 33 ++- .../data/mapper/book/BookMapperImpl.kt | 9 +- 5 files changed, 260 insertions(+), 6 deletions(-) create mode 100644 app/schemas/ua.acclorite.book_story.data.local.room.BookDatabase/15.json diff --git a/app/schemas/ua.acclorite.book_story.data.local.room.BookDatabase/15.json b/app/schemas/ua.acclorite.book_story.data.local.room.BookDatabase/15.json new file mode 100644 index 00000000..65190d34 --- /dev/null +++ b/app/schemas/ua.acclorite.book_story.data.local.room.BookDatabase/15.json @@ -0,0 +1,221 @@ +{ + "formatVersion": 1, + "database": { + "version": 15, + "identityHash": "34a325ef104d83604c6d21d765c901b8", + "entities": [ + { + "tableName": "BookEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `author` TEXT NOT NULL, `description` TEXT, `filePath` TEXT NOT NULL, `scrollIndex` INTEGER NOT NULL, `scrollOffset` INTEGER NOT NULL, `progress` REAL NOT NULL, `image` TEXT, `categories` TEXT NOT NULL DEFAULT '[]')", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "author", + "columnName": "author", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT" + }, + { + "fieldPath": "filePath", + "columnName": "filePath", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "scrollIndex", + "columnName": "scrollIndex", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "scrollOffset", + "columnName": "scrollOffset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "progress", + "columnName": "progress", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "image", + "columnName": "image", + "affinity": "TEXT" + }, + { + "fieldPath": "categories", + "columnName": "categories", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "'[]'" + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + } + }, + { + "tableName": "HistoryEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `bookId` INTEGER NOT NULL, `time` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "bookId", + "columnName": "bookId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "time", + "columnName": "time", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + } + }, + { + "tableName": "ColorPresetEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL, `backgroundColor` INTEGER NOT NULL, `fontColor` INTEGER NOT NULL, `isSelected` INTEGER NOT NULL, `order` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER" + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "backgroundColor", + "columnName": "backgroundColor", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "fontColor", + "columnName": "fontColor", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isSelected", + "columnName": "isSelected", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + } + }, + { + "tableName": "CategoryEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `order` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + } + }, + { + "tableName": "CategorySortEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`categoryId` INTEGER NOT NULL, `sortOrder` TEXT NOT NULL, `sortOrderDescending` INTEGER NOT NULL, PRIMARY KEY(`categoryId`))", + "fields": [ + { + "fieldPath": "categoryId", + "columnName": "categoryId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sortOrder", + "columnName": "sortOrder", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sortOrderDescending", + "columnName": "sortOrderDescending", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "categoryId" + ] + } + } + ], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '34a325ef104d83604c6d21d765c901b8')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/data/di/AppModule.kt b/app/src/main/java/ua/acclorite/book_story/data/di/AppModule.kt index 60ac3010..babcaeef 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/di/AppModule.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/di/AppModule.kt @@ -61,6 +61,7 @@ object AppModule { DatabaseHelper.MIGRATION_4_5, // creates ColorPresetEntity table(if does not exist) DatabaseHelper.MIGRATION_5_6, // creates FavoriteDirectoryEntity table(if does not exist) DatabaseHelper.MIGRATION_13_14, // remove nullability from ColorPresetEntity + DatabaseHelper.MIGRATION_14_15, // remove author nullability from BookEntity ).allowMainThreadQueries().build() } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/data/local/dto/BookEntity.kt b/app/src/main/java/ua/acclorite/book_story/data/local/dto/BookEntity.kt index 1d2ef56e..b18d95a1 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/local/dto/BookEntity.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/local/dto/BookEntity.kt @@ -17,7 +17,7 @@ import ua.acclorite.book_story.data.converter.CategoryConverter data class BookEntity( @PrimaryKey(true) val id: Int = 0, val title: String, - val author: String?, + val author: String, val description: String?, val filePath: String, val scrollIndex: Int, diff --git a/app/src/main/java/ua/acclorite/book_story/data/local/room/BookDatabase.kt b/app/src/main/java/ua/acclorite/book_story/data/local/room/BookDatabase.kt index 5ffc2983..7b72e9fe 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/local/room/BookDatabase.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/local/room/BookDatabase.kt @@ -30,7 +30,7 @@ import java.io.File CategoryEntity::class, CategorySortEntity::class ], - version = 14, + version = 15, autoMigrations = [ AutoMigration(1, 2), AutoMigration(2, 3), @@ -45,6 +45,7 @@ import java.io.File AutoMigration(11, 12), AutoMigration(12, 13), AutoMigration(13, 14), + AutoMigration(14, 15), ], exportSchema = true ) @@ -159,4 +160,34 @@ object DatabaseHelper { database.execSQL("ALTER TABLE ColorPresetEntity_new RENAME TO ColorPresetEntity") } } + + val MIGRATION_14_15 = object : Migration(14, 15) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL( + """ + CREATE TABLE BookEntity_new ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + title TEXT NOT NULL, + author TEXT NOT NULL, + description TEXT, + filePath TEXT NOT NULL, + scrollIndex INTEGER NOT NULL, + scrollOffset INTEGER NOT NULL, + progress REAL NOT NULL, + image TEXT, + categories TEXT NOT NULL DEFAULT '[]' + ) + """ + ) + database.execSQL( + """ + INSERT INTO BookEntity_new (id, title, author, description, filePath, scrollIndex, scrollOffset, progress, image, categories) + SELECT id, title, COALESCE(author, ''), description, filePath, scrollIndex, scrollOffset, progress, image, categories + FROM BookEntity + """ + ) + database.execSQL("DROP TABLE BookEntity") + database.execSQL("ALTER TABLE BookEntity_new RENAME TO BookEntity") + } + } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/data/mapper/book/BookMapperImpl.kt b/app/src/main/java/ua/acclorite/book_story/data/mapper/book/BookMapperImpl.kt index 911620eb..1ab2105c 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/mapper/book/BookMapperImpl.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/mapper/book/BookMapperImpl.kt @@ -22,7 +22,7 @@ class BookMapperImpl @Inject constructor() : BookMapper { scrollIndex = book.scrollIndex, scrollOffset = book.scrollOffset, progress = book.progress, - author = book.author.getAsString(), + author = book.author.getAsString() ?: "", description = book.description, image = book.coverImage?.toString(), categories = book.categories @@ -33,9 +33,10 @@ class BookMapperImpl @Inject constructor() : BookMapper { return Book( id = bookEntity.id, title = bookEntity.title, - author = bookEntity.author?.let { UIText.StringValue(it) } ?: UIText.StringResource( - R.string.unknown_author - ), + author = bookEntity.author.let { author -> + if (author.isNotBlank()) UIText.StringValue(author) + else UIText.StringResource(R.string.unknown_author) + }, description = bookEntity.description, scrollIndex = bookEntity.scrollIndex, scrollOffset = bookEntity.scrollOffset,