数据库重构

v4
laoyuyu 2 years ago
parent 616724a762
commit ac9f9eb6b8
  1. 12
      Aria/src/main/java/com/arialyy/aria/core/provider/IdbProvider.kt
  2. 2
      PublicComponent/build.gradle
  3. 2
      PublicComponent/src/main/AndroidManifest.xml
  4. 35
      PublicComponent/src/main/java/com/arialyy/aria/core/DuaContext.kt
  5. 43
      PublicComponent/src/main/java/com/arialyy/aria/core/provider/DuaStartupProvider.kt
  6. 3
      PublicComponent/src/main/java/com/arialyy/aria/core/provider/IDbProvider.kt
  7. 35
      PublicComponent/src/main/java/com/arialyy/aria/core/service/DbService.kt
  8. 28
      PublicComponent/src/main/java/com/arialyy/aria/core/service/IService.kt
  9. 56
      PublicComponent/src/main/java/com/arialyy/aria/core/service/ServiceManager.kt
  10. 44
      PublicComponent/src/main/java/com/arialyy/aria/orm/DGUrlConverter.kt
  11. 2
      PublicComponent/src/main/java/com/arialyy/aria/orm/DefaultDbProvider.kt
  12. 6
      PublicComponent/src/main/java/com/arialyy/aria/orm/DuaDb.kt
  13. 46
      PublicComponent/src/main/java/com/arialyy/aria/orm/dao/DEntityDao.kt
  14. 46
      PublicComponent/src/main/java/com/arialyy/aria/orm/dao/UEntityDao.kt
  15. 8
      PublicComponent/src/main/java/com/arialyy/aria/orm/entiry/DEntity.kt
  16. 62
      PublicComponent/src/main/java/com/arialyy/aria/orm/entiry/DGEntity.kt
  17. 28
      PublicComponent/src/main/java/com/arialyy/aria/orm/entiry/DGSubList.kt
  18. 8
      PublicComponent/src/main/java/com/arialyy/aria/orm/entiry/UEntity.kt
  19. 4
      libs.versions.toml

@ -1,12 +0,0 @@
package com.arialyy.aria.core.provider
import androidx.room.RoomDatabase
/**
* @Author laoyuyu
* @Description
* @Date 19:32 PM 2023/1/13
**/
interface IdbProvider {
fun initDb()
}

@ -35,6 +35,8 @@ dependencies {
implementation(libs.appcompat) implementation(libs.appcompat)
implementation(libs.bundles.room) implementation(libs.bundles.room)
implementation(libs.startup) implementation(libs.startup)
implementation(libs.timber)
implementation(libs.gson)
kapt libs.room.compiler kapt libs.room.compiler
} }

@ -12,7 +12,7 @@
android:exported="false" android:exported="false"
tools:node="merge"> tools:node="merge">
<!-- This entry makes ExampleLoggerInitializer discoverable. --> <!-- This entry makes ExampleLoggerInitializer discoverable. -->
<meta-data android:name="com.arialyy.aria.core.DuaStartupProvider" <meta-data android:name="com.arialyy.aria.core.provider.DuaStartupProvider"
android:value="androidx.startup" /> android:value="androidx.startup" />
</provider> </provider>
</application> </application>

@ -0,0 +1,35 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core
import android.annotation.SuppressLint
import com.arialyy.aria.core.service.ServiceManager
/**
* @Author laoyuyu
* @Description
* @Date 10:40 AM 2023/1/16
**/
@SuppressLint("StaticFieldLeak")
internal object DuaContext {
const val DB_SERVICE = "DB_SERVICE"
private val serviceArray = arrayOf(DB_SERVICE)
fun isService(serviceName: String) = serviceName in serviceArray
fun getServiceManager() = ServiceManager
}

@ -0,0 +1,43 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.provider
import android.content.Context
import androidx.startup.Initializer
import com.arialyy.aria.core.DuaContext
import com.arialyy.aria.core.service.DbService
import timber.log.Timber
import timber.log.Timber.DebugTree
class DuaStartupProvider : Initializer<Unit> {
override fun create(context: Context) {
DuaContext.getServiceManager().let {
it.registerService(DuaContext.DB_SERVICE, context, DbService::class.java)
}
initLog()
}
private fun initLog() {
if (Timber.treeCount == 0) {
Timber.plant(DebugTree())
}
}
override fun dependencies(): MutableList<Class<out Initializer<*>>> {
return mutableListOf()
}
}

@ -17,10 +17,11 @@ package com.arialyy.aria.core.provider
import android.content.Context import android.content.Context
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import com.arialyy.aria.orm.DuaDb
interface IDbProvider { interface IDbProvider {
fun getDbName() = "duaDb" fun getDbName() = "duaDb"
fun <T : RoomDatabase> generateDb(context: Context): RoomDatabase.Builder<T> fun <T : DuaDb> generateDb(context: Context): RoomDatabase.Builder<T>
} }

@ -13,22 +13,27 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.arialyy.aria.core package com.arialyy.aria.core.service
import android.content.Context import android.content.Context
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.RoomDatabase.Builder import androidx.room.RoomDatabase.Builder
import androidx.startup.Initializer
import com.arialyy.aria.core.config.AutoGenerateConstance import com.arialyy.aria.core.config.AutoGenerateConstance
import com.arialyy.aria.orm.DefaultDbProvider import com.arialyy.aria.orm.DefaultDbProvider
import com.arialyy.aria.orm.DuaDb
import com.arialyy.aria.util.ReflectionUtil import com.arialyy.aria.util.ReflectionUtil
class DuaStartupProvider : Initializer<Unit> { /**
* @Author laoyuyu
* @Description
* @Date 19:36 AM 2023/1/16
**/
open class DbService : IService {
private var duaDb: DuaDb? = null
/** /**
* Find a user-defined database * Find a user-defined database
*/ */
private fun findCustomDatabase(context: Context): Builder<RoomDatabase>? { private fun findCustomDatabase(context: Context): Builder<DuaDb>? {
try { try {
val clazz = javaClass.classLoader.loadClass(AutoGenerateConstance.GenerateClassName) val clazz = javaClass.classLoader.loadClass(AutoGenerateConstance.GenerateClassName)
?: return null ?: return null
@ -37,22 +42,24 @@ class DuaStartupProvider : Initializer<Unit> {
val method = ReflectionUtil.getMethod(clazz, "generateDb", Context::class.java) ?: return null val method = ReflectionUtil.getMethod(clazz, "generateDb", Context::class.java) ?: return null
return method.invoke(obj, context) as Builder<RoomDatabase>? return method.invoke(obj, context) as Builder<DuaDb>?
} catch (e: java.lang.Exception) { } catch (e: java.lang.Exception) {
return null return null
} }
} }
override fun create(context: Context) { // fun findDEntity(dId: Int): DEntity? {
// if (duaDb == null) {
// return null
// }
// }
override fun init(context: Context) {
var customDb = findCustomDatabase(context) var customDb = findCustomDatabase(context)
if (customDb == null) { if (customDb == null) {
customDb = DefaultDbProvider().generateDb(context) customDb = DefaultDbProvider().generateDb(context)
} }
customDb.build() duaDb = customDb
// .addMigrations(MIGRATION_2_3(), MIGRATION_3_4()) .build()
}
override fun dependencies(): MutableList<Class<out Initializer<*>>> {
return mutableListOf()
} }
} }

@ -0,0 +1,28 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.service
import android.content.Context
/**
* @Author laoyuyu
* @Description
* @Date 19:34 AM 2023/1/16
**/
internal interface IService {
fun init(context: Context)
}

@ -0,0 +1,56 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.service
import android.content.Context
import com.arialyy.aria.core.DuaContext
import com.arialyy.aria.exception.AriaException
import timber.log.Timber
object ServiceManager {
private val serviceCache = hashMapOf<String, IService>()
private fun getServiceName(clazz: Class<*>) = clazz.name
/**
* register a service
* @param serviceName [DuaContext.DB_SERVICE]
*/
fun <T : IService> registerService(serviceName: String, context: Context, clazz: Class<T>) {
if (!DuaContext.isService(serviceName)) {
throw AriaException("$serviceName Not a service.")
}
val sn = getServiceName(clazz)
val service = serviceCache[sn]
if (service == null) {
Timber.d("start register service: $sn")
val s = clazz.newInstance()
s.init(context)
serviceCache[serviceName] = s
}
}
/**
* get datebase service, if already [registerService] custom service, return custom service
*/
fun getDbService(serviceName: String): DbService {
if (!DuaContext.isService(serviceName)) {
throw AriaException("$serviceName Not a service.")
}
return (serviceCache[serviceName]
?: throw AriaException("service not found: $serviceName")) as DbService
}
}

@ -0,0 +1,44 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.orm
import androidx.room.ProvidedTypeConverter
import androidx.room.TypeConverter
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
/**
* @Author laoyuyu
* @Description
* @Date 7:24 PM 2023/1/16
**/
@ProvidedTypeConverter
class DGUrlConverter {
private val gson by lazy {
Gson()
}
@TypeConverter
fun stringToList(string: String?): List<String> {
if (string.isNullOrEmpty()) return emptyList()
return gson.fromJson(string, object : TypeToken<List<String>>() {}.type)
}
@TypeConverter
fun listToString(strList: List<String>): String {
return gson.toJson(strList)
}
}

@ -23,7 +23,7 @@ import com.arialyy.aria.core.provider.IDbProvider
class DefaultDbProvider : IDbProvider { class DefaultDbProvider : IDbProvider {
override fun <T : RoomDatabase> generateDb(context: Context): Builder<T> { override fun <T : DuaDb> generateDb(context: Context): Builder<T> {
return Room.databaseBuilder( return Room.databaseBuilder(
context, context,
DuaDb::class.java, getDbName() DuaDb::class.java, getDbName()

@ -17,6 +17,8 @@ package com.arialyy.aria.orm
import androidx.room.Database import androidx.room.Database
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import com.arialyy.aria.orm.dao.DEntityDao
import com.arialyy.aria.orm.dao.UEntityDao
import com.arialyy.aria.orm.entiry.UEntity import com.arialyy.aria.orm.entiry.UEntity
@Database( @Database(
@ -24,7 +26,7 @@ import com.arialyy.aria.orm.entiry.UEntity
version = 1 version = 1
) )
abstract class DuaDb : RoomDatabase() { abstract class DuaDb : RoomDatabase() {
companion object { abstract fun getDEntityDao(): DEntityDao
} abstract fun getUEntityDao(): UEntityDao
} }

@ -0,0 +1,46 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.orm.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.arialyy.aria.orm.entiry.DEntity
/**
* @Author laoyuyu
* @Description
* @Date 19:23 AM 2023/1/16
**/
@Dao
interface DEntityDao {
@Query("SELECT * FROM DEntity WHERE :dId=dId")
suspend fun queryDEntityById(dId: String): DEntity
@Query("SELECT * FROM DEntity WHERE :sourceUrl=sourceUrl")
suspend fun queryDEntityBySource(sourceUrl: String): DEntity
@Insert
suspend fun insert(dEntity: DEntity)
@Update
suspend fun update(dEntity: DEntity)
@Delete
suspend fun delete(dEntity: DEntity)
}

@ -0,0 +1,46 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.orm.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.arialyy.aria.orm.entiry.UEntity
/**
* @Author laoyuyu
* @Description
* @Date 19:23 AM 2023/1/16
**/
@Dao
interface UEntityDao {
@Query("SELECT * FROM DEntity WHERE :uId=uId")
suspend fun queryUEntityById(uId: String): UEntity
@Query("SELECT * FROM UEntity WHERE :filePath=filePath")
suspend fun queryUEntityBySource(filePath: String): UEntity
@Insert
suspend fun insert(uEntity: UEntity)
@Update
suspend fun update(uEntity: UEntity)
@Delete
suspend fun delete(uEntity: UEntity)
}

@ -22,7 +22,7 @@ import androidx.room.PrimaryKey
/** /**
* Download Entity * Download Entity
*/ */
@Entity(tableName = "d_entity", indices = [Index(value = ["sourceUrl", "savePath"])]) @Entity(indices = [Index(value = ["sourceUrl", "savePath"])])
data class DEntity( data class DEntity(
@PrimaryKey(autoGenerate = true) val dId: Int = 0, @PrimaryKey(autoGenerate = true) val dId: Int = 0,
@ -37,5 +37,9 @@ data class DEntity(
/** /**
* extended Information * extended Information
*/ */
var ext: String? = null var ext: String? = null,
val createTime: Long,
val updateTime: Long
) )

@ -0,0 +1,62 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.orm.entiry
import androidx.room.Entity
import androidx.room.PrimaryKey
import androidx.room.TypeConverters
import com.arialyy.aria.orm.DGUrlConverter
/**
* @Author laoyuyu
* @Description
* @Date 4:32 PM 2023/1/16
**/
@Entity
@TypeConverters(DGUrlConverter::class)
data class DGEntity(
@PrimaryKey(autoGenerate = true) val dgId: Int = 0,
/**
* 组合任务等hash为 为子任务地址相加的url的Md5
* ftpdir为ftpdir下载地址
*/
val groupHash: String,
/**
* 任务组别名
*/
val alias: String? = null,
/**
* 保存路径
*/
val savePath: String,
/**
* 子任务url地址
*/
val urls: List<String>,
/**
* extended Information
*/
var ext: String? = null,
val createTime: Long,
val updateTime: Long
)

@ -0,0 +1,28 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.orm.entiry
import androidx.room.Embedded
import androidx.room.Relation
data class DGSubList(
@Embedded val dgEntity: DGEntity,
@Relation(
parentColumn = "dgId",
entityColumn = "dId"
)
val subEntity: List<DEntity>
)

@ -19,7 +19,7 @@ import androidx.room.Entity
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
@Entity(tableName = "u_entity", indices = [Index(value = ["serverUrl", "filePath"])]) @Entity(indices = [Index(value = ["serverUrl", "filePath"])])
data class UEntity( data class UEntity(
@PrimaryKey(autoGenerate = true) val uId: Int = 0, @PrimaryKey(autoGenerate = true) val uId: Int = 0,
/** /**
@ -35,5 +35,9 @@ data class UEntity(
/** /**
* extended Information * extended Information
*/ */
var ext: String? = null var ext: String? = null,
val createTime: Long,
val updateTime: Long
) )

@ -12,6 +12,8 @@ android-espresso = "3.5.0"
android-ktx = "1.7.0" android-ktx = "1.7.0"
lifecycle = "2.5.1" lifecycle = "2.5.1"
startup = "1.1.1" startup = "1.1.1"
timber = "5.0.1"
gson = "2.10.1"
[libraries] [libraries]
@ -28,6 +30,8 @@ lifecycle-viewmodel-ktx = {module = "androidx.lifecycle:lifecycle-viewmodel-ktx"
lifecycle-viewmodel-compose = {module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle"} lifecycle-viewmodel-compose = {module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle"}
lifecycle-runtime-ktx = {module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle"} lifecycle-runtime-ktx = {module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle"}
startup = {module = "androidx.startup:startup-runtime", version.ref = "startup"} startup = {module = "androidx.startup:startup-runtime", version.ref = "startup"}
timber = {module = "com.jakewharton.timber:timber", version.ref = "timber"}
gson = {module = "com.google.code.gson:gson", version.ref = "gson"}
[bundles] [bundles]
room = ["room-runtime", "room-common"] room = ["room-runtime", "room-common"]

Loading…
Cancel
Save