114 lines
4.0 KiB
Kotlin
114 lines
4.0 KiB
Kotlin
/*
|
|
* Copyright 2024 ObjectBox Ltd. All rights reserved.
|
|
*
|
|
* 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.sw.dualscreen.objbox
|
|
|
|
import android.content.Context
|
|
import android.util.Log
|
|
import io.objectbox.BoxStore
|
|
import io.objectbox.BoxStoreBuilder
|
|
import io.objectbox.android.Admin
|
|
import io.objectbox.android.ObjectBoxLiveData
|
|
import io.objectbox.exception.DbException
|
|
import io.objectbox.exception.FileCorruptException
|
|
import io.objectbox.sync.Sync
|
|
import timber.log.Timber
|
|
import java.io.File
|
|
import java.util.Date
|
|
import java.util.zip.GZIPOutputStream
|
|
import kotlin.also
|
|
import kotlin.io.copyTo
|
|
import kotlin.io.inputStream
|
|
import kotlin.io.outputStream
|
|
import kotlin.io.use
|
|
import kotlin.jvm.java
|
|
import kotlin.jvm.javaClass
|
|
|
|
/**
|
|
* Singleton to keep BoxStore reference and provide current list of Notes Objects.
|
|
* Inserts demo data if no Objects are stored.
|
|
*/
|
|
object ObjectBox {
|
|
|
|
// 确保所有设备/版本使用相同的objectbox-models/default.json
|
|
// 避免直接修改自动生成的MyObjectBox类
|
|
// 跨版本升级时使用boxStore.runInTx执行数据迁移
|
|
|
|
|
|
private const val TAG = "ObjectBox"
|
|
|
|
lateinit var boxStore: BoxStore
|
|
private set
|
|
|
|
/**
|
|
* If building the [boxStore] failed, contains the thrown error message.
|
|
*/
|
|
var dbExceptionMessage: String? = null
|
|
private set
|
|
|
|
fun init(context: Context) {
|
|
// On Android make sure to pass a Context when building the Store.
|
|
boxStore = try {
|
|
MyObjectBox.builder()
|
|
.androidContext(context.applicationContext)
|
|
.build()
|
|
} catch (e: DbException) {
|
|
if (e.javaClass == DbException::class.java || e is FileCorruptException) {
|
|
// Failed to build BoxStore due to database file issue, store message;
|
|
// checked in NoteListActivity to notify user.
|
|
dbExceptionMessage = e.toString()
|
|
return
|
|
} else {
|
|
// Failed to build BoxStore due to developer error.
|
|
throw e
|
|
}
|
|
}
|
|
|
|
// if (BuildConfig.DEBUG) {
|
|
val syncAvailable = if (Sync.isAvailable()) "available" else "unavailable"
|
|
Timber.tag(TAG)
|
|
.d("Using ObjectBox ${BoxStore.getVersion()} (${BoxStore.getVersionNative()}, sync $syncAvailable)")
|
|
// Enable ObjectBox Admin on debug builds.
|
|
// https://docs.objectbox.io/data-browser
|
|
Admin(boxStore).start(context.applicationContext)
|
|
// }
|
|
}
|
|
|
|
|
|
/**
|
|
* If the database file is not in use, compresses (GZIP) and copies it to the given [target].
|
|
*/
|
|
fun copyAndGzipDatabaseFileTo(target: File, context: Context): Boolean {
|
|
if (BoxStore.isDatabaseOpen(context, null)) {
|
|
// Do not copy if database file is still in use.
|
|
// If it would be open, the copy will likely get corrupted
|
|
// as BoxStore may currently write data to the file.
|
|
Timber.tag(TAG).e("Database file is still in use, can not copy.")
|
|
return false
|
|
}
|
|
|
|
// If a name was given when building BoxStore use that instead of the default below.
|
|
val dbName = BoxStoreBuilder.DEFAULT_NAME
|
|
File(context.filesDir, "objectbox/$dbName/data.mdb").inputStream().use { input ->
|
|
target.parentFile?.mkdirs()
|
|
GZIPOutputStream(target.outputStream()).use { output ->
|
|
input.copyTo(output, DEFAULT_BUFFER_SIZE)
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
} |