|
@@ -1,57 +1,21 @@
|
|
|
package com.grkj.data.database
|
|
package com.grkj.data.database
|
|
|
|
|
|
|
|
|
|
+import android.os.Environment
|
|
|
|
|
+import android.util.Log
|
|
|
import androidx.room.Database
|
|
import androidx.room.Database
|
|
|
import androidx.room.Room
|
|
import androidx.room.Room
|
|
|
import androidx.room.RoomDatabase
|
|
import androidx.room.RoomDatabase
|
|
|
import androidx.room.TypeConverters
|
|
import androidx.room.TypeConverters
|
|
|
import com.grkj.data.converters.Converters
|
|
import com.grkj.data.converters.Converters
|
|
|
-import com.grkj.data.dao.ExceptionDao
|
|
|
|
|
-import com.grkj.data.dao.HardwareDao
|
|
|
|
|
-import com.grkj.data.dao.IsSopDao
|
|
|
|
|
-import com.grkj.data.dao.IsolationPointDao
|
|
|
|
|
-import com.grkj.data.dao.JobTicketDao
|
|
|
|
|
-import com.grkj.data.dao.RfidTokenDao
|
|
|
|
|
-import com.grkj.data.dao.RoleDao
|
|
|
|
|
-import com.grkj.data.dao.SysMenuDao
|
|
|
|
|
-import com.grkj.data.dao.UserDao
|
|
|
|
|
-import com.grkj.data.dao.WorkflowStepDao
|
|
|
|
|
-import com.grkj.data.dao.WorkstationDao
|
|
|
|
|
-import com.grkj.data.model.dos.IsExceptionSourceStandard
|
|
|
|
|
-import com.grkj.data.model.dos.IsExceptionStandard
|
|
|
|
|
-import com.grkj.data.model.dos.IsIsolationPoint
|
|
|
|
|
-import com.grkj.data.model.dos.IsJobCard
|
|
|
|
|
-import com.grkj.data.model.dos.IsJobTicket
|
|
|
|
|
-import com.grkj.data.model.dos.IsJobTicketKey
|
|
|
|
|
-import com.grkj.data.model.dos.IsJobTicketLock
|
|
|
|
|
-import com.grkj.data.model.dos.IsJobTicketPoints
|
|
|
|
|
-import com.grkj.data.model.dos.IsJobTicketStep
|
|
|
|
|
-import com.grkj.data.model.dos.IsJobTicketUser
|
|
|
|
|
-import com.grkj.data.model.dos.IsKey
|
|
|
|
|
-import com.grkj.data.model.dos.IsLock
|
|
|
|
|
-import com.grkj.data.model.dos.IsLockCabinet
|
|
|
|
|
-import com.grkj.data.model.dos.IsLockCabinetSlots
|
|
|
|
|
-import com.grkj.data.model.dos.IsLockset
|
|
|
|
|
-import com.grkj.data.model.dos.IsLocksetType
|
|
|
|
|
-import com.grkj.data.model.dos.IsRfidToken
|
|
|
|
|
-import com.grkj.data.model.dos.IsSop
|
|
|
|
|
-import com.grkj.data.model.dos.IsSopPoints
|
|
|
|
|
-import com.grkj.data.model.dos.IsSopUser
|
|
|
|
|
-import com.grkj.data.model.dos.IsUserWorkstation
|
|
|
|
|
-import com.grkj.data.model.dos.IsWorkstation
|
|
|
|
|
-import com.grkj.data.model.dos.SysMenu
|
|
|
|
|
-import com.grkj.data.model.dos.SysRole
|
|
|
|
|
-import com.grkj.data.model.dos.SysRoleMenu
|
|
|
|
|
-import com.grkj.data.model.dos.SysUserCharacteristicDo
|
|
|
|
|
-import com.grkj.data.model.dos.SysUserDo
|
|
|
|
|
-import com.grkj.data.model.dos.SysUserRole
|
|
|
|
|
-import com.grkj.data.model.dos.WorkflowMode
|
|
|
|
|
-import com.grkj.data.model.dos.WorkflowStep
|
|
|
|
|
-import com.grkj.data.model.dos.WorkflowStepTemplate
|
|
|
|
|
|
|
+import com.grkj.data.dao.*
|
|
|
|
|
+import com.grkj.data.model.dos.*
|
|
|
import com.grkj.shared.config.Constants
|
|
import com.grkj.shared.config.Constants
|
|
|
import com.sik.sikcore.SIKCore
|
|
import com.sik.sikcore.SIKCore
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
import org.slf4j.Logger
|
|
import org.slf4j.Logger
|
|
|
import org.slf4j.LoggerFactory
|
|
import org.slf4j.LoggerFactory
|
|
|
|
|
+import java.io.File
|
|
|
|
|
+import java.io.FileOutputStream
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 本地数据库
|
|
* 本地数据库
|
|
@@ -62,53 +26,83 @@ import org.slf4j.LoggerFactory
|
|
|
SysRole::class, SysUserRole::class, IsUserWorkstation::class, IsWorkstation::class, IsIsolationPoint::class, IsRfidToken::class,
|
|
SysRole::class, SysUserRole::class, IsUserWorkstation::class, IsWorkstation::class, IsIsolationPoint::class, IsRfidToken::class,
|
|
|
IsSop::class, IsSopUser::class, IsSopPoints::class, IsJobTicket::class, IsJobTicketKey::class, IsJobTicketLock::class,
|
|
IsSop::class, IsSopUser::class, IsSopPoints::class, IsJobTicket::class, IsJobTicketKey::class, IsJobTicketLock::class,
|
|
|
IsJobTicketPoints::class, IsJobTicketStep::class, IsJobTicketUser::class,
|
|
IsJobTicketPoints::class, IsJobTicketStep::class, IsJobTicketUser::class,
|
|
|
- IsKey::class, IsLock::class, IsLockCabinet::class, IsLockCabinetSlots::class, IsLocksetType::class, IsLockset::class, SysMenu::class, SysRoleMenu::class,
|
|
|
|
|
- WorkflowStep::class, WorkflowMode::class, WorkflowStepTemplate::class, IsExceptionStandard::class, IsExceptionSourceStandard::class
|
|
|
|
|
|
|
+ IsKey::class, IsLock::class, IsLockCabinet::class, IsLockCabinetSlots::class, IsLocksetType::class, IsLockset::class,
|
|
|
|
|
+ SysMenu::class, SysRoleMenu::class,
|
|
|
|
|
+ WorkflowStep::class, WorkflowMode::class, WorkflowStepTemplate::class,
|
|
|
|
|
+ IsExceptionStandard::class, IsExceptionSourceStandard::class, IsSopGroup::class, IsJobTicketGroup::class
|
|
|
],
|
|
],
|
|
|
version = ISCSMigrations.VERSION,
|
|
version = ISCSMigrations.VERSION,
|
|
|
exportSchema = true
|
|
exportSchema = true
|
|
|
)
|
|
)
|
|
|
-@TypeConverters(Converters::class) // 注册下面要写的 Converters
|
|
|
|
|
|
|
+@TypeConverters(Converters::class)
|
|
|
abstract class ISCSDatabase : RoomDatabase() {
|
|
abstract class ISCSDatabase : RoomDatabase() {
|
|
|
- companion object {
|
|
|
|
|
- private val logger: Logger = LoggerFactory.getLogger(ISCSDatabase::class.java)
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 单例
|
|
|
|
|
- */
|
|
|
|
|
- @JvmStatic
|
|
|
|
|
- val instance: ISCSDatabase by lazy {
|
|
|
|
|
- Room.databaseBuilder(
|
|
|
|
|
- SIKCore.getApplication(), ISCSDatabase::class.java, "iscs_database"
|
|
|
|
|
- ).apply {
|
|
|
|
|
- if (Constants.DEBUG) {
|
|
|
|
|
-// fallbackToDestructiveMigration(true)
|
|
|
|
|
- }
|
|
|
|
|
- }.createFromAsset("data.db").setQueryCallback(Dispatchers.IO) { sql, args ->
|
|
|
|
|
- logger.debug("SQL:$sql,Args:$args")
|
|
|
|
|
- }.build()
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
abstract fun userDao(): UserDao
|
|
abstract fun userDao(): UserDao
|
|
|
-
|
|
|
|
|
abstract fun hardwareDao(): HardwareDao
|
|
abstract fun hardwareDao(): HardwareDao
|
|
|
-
|
|
|
|
|
abstract fun roleDao(): RoleDao
|
|
abstract fun roleDao(): RoleDao
|
|
|
-
|
|
|
|
|
abstract fun workstationDao(): WorkstationDao
|
|
abstract fun workstationDao(): WorkstationDao
|
|
|
-
|
|
|
|
|
abstract fun isolationPointDao(): IsolationPointDao
|
|
abstract fun isolationPointDao(): IsolationPointDao
|
|
|
-
|
|
|
|
|
abstract fun rfidTokenDao(): RfidTokenDao
|
|
abstract fun rfidTokenDao(): RfidTokenDao
|
|
|
-
|
|
|
|
|
abstract fun isSopDao(): IsSopDao
|
|
abstract fun isSopDao(): IsSopDao
|
|
|
-
|
|
|
|
|
abstract fun jobTicketDao(): JobTicketDao
|
|
abstract fun jobTicketDao(): JobTicketDao
|
|
|
-
|
|
|
|
|
abstract fun sysMenuDao(): SysMenuDao
|
|
abstract fun sysMenuDao(): SysMenuDao
|
|
|
-
|
|
|
|
|
abstract fun workflowStepDao(): WorkflowStepDao
|
|
abstract fun workflowStepDao(): WorkflowStepDao
|
|
|
-
|
|
|
|
|
abstract fun exceptionDao(): ExceptionDao
|
|
abstract fun exceptionDao(): ExceptionDao
|
|
|
-}
|
|
|
|
|
|
|
+
|
|
|
|
|
+ companion object {
|
|
|
|
|
+ private const val DB_NAME = "iscs_database.db"
|
|
|
|
|
+ private val logger: Logger = LoggerFactory.getLogger(ISCSDatabase::class.java)
|
|
|
|
|
+
|
|
|
|
|
+ // 外部存储目录路径
|
|
|
|
|
+ private val EXTERNAL_DB_FILE: File by lazy {
|
|
|
|
|
+ File(Environment.getExternalStorageDirectory(), "ISCS/database/$DB_NAME")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @JvmStatic
|
|
|
|
|
+ val instance: ISCSDatabase by lazy {
|
|
|
|
|
+ val context = SIKCore.getApplication()
|
|
|
|
|
+
|
|
|
|
|
+ // 检查并创建外部目录
|
|
|
|
|
+ val parentDir = EXTERNAL_DB_FILE.parentFile
|
|
|
|
|
+ if (parentDir != null) {
|
|
|
|
|
+ if (!parentDir.exists()) {
|
|
|
|
|
+ val ok = parentDir.mkdirs()
|
|
|
|
|
+ if (!ok) {
|
|
|
|
|
+ Log.e("ISCSDatabase", "无法创建目录: ${parentDir.absolutePath}")
|
|
|
|
|
+ } else {
|
|
|
|
|
+ logger.info("创建目录: ${parentDir.absolutePath}")
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 若文件不存在,从 assets 拷贝
|
|
|
|
|
+ if (!EXTERNAL_DB_FILE.exists()) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ context.assets.open("data.db").use { input ->
|
|
|
|
|
+ FileOutputStream(EXTERNAL_DB_FILE).use { output ->
|
|
|
|
|
+ input.copyTo(output)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ logger.info("已从 assets 复制数据库到: ${EXTERNAL_DB_FILE.absolutePath}")
|
|
|
|
|
+ } catch (e: Exception) {
|
|
|
|
|
+ logger.error("复制数据库失败", e)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 构建 RoomDatabase,使用外部存储路径
|
|
|
|
|
+ val builder = Room.databaseBuilder(
|
|
|
|
|
+ context,
|
|
|
|
|
+ ISCSDatabase::class.java,
|
|
|
|
|
+ EXTERNAL_DB_FILE.absolutePath
|
|
|
|
|
+ )
|
|
|
|
|
+ if (Constants.DEBUG) {
|
|
|
|
|
+ builder.setQueryCallback( Dispatchers.IO,{ sql, args ->
|
|
|
|
|
+ logger.debug("SQL: $sql, args: $args")
|
|
|
|
|
+ })
|
|
|
|
|
+ // 不要使用 fallbackToDestructiveMigration()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ builder.build()
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|