Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 是否可以使用sqldelight从本地资源加载预填充的数据库_Kotlin_Kotlin Multiplatform_Sqldelight - Fatal编程技术网

Kotlin 是否可以使用sqldelight从本地资源加载预填充的数据库

Kotlin 是否可以使用sqldelight从本地资源加载预填充的数据库,kotlin,kotlin-multiplatform,sqldelight,Kotlin,Kotlin Multiplatform,Sqldelight,我有一个相对较大的数据库,可能需要1到2分钟来初始化,在使用sqldelight(kotlin multiplatform)而不是在应用程序启动时初始化数据库时,是否可以加载预填充的数据库?是的,但这可能很棘手。不仅仅是“多平台”。在尝试初始化sqldelight之前,需要将db复制到db文件夹。这可能意味着应用程序启动时主线程上的i/o 现在没有标准的方法可以做到这一点。在初始化sqldelight之前,您需要将db文件放在android上的资产中,以及iOS上的捆绑包中,并将它们复制到各自的

我有一个相对较大的数据库,可能需要1到2分钟来初始化,在使用sqldelight(kotlin multiplatform)而不是在应用程序启动时初始化数据库时,是否可以加载预填充的数据库?

是的,但这可能很棘手。不仅仅是“多平台”。在尝试初始化sqldelight之前,需要将db复制到db文件夹。这可能意味着应用程序启动时主线程上的i/o

现在没有标准的方法可以做到这一点。在初始化sqldelight之前,您需要将db文件放在android上的资产中,以及iOS上的捆绑包中,并将它们复制到各自的文件夹中。很明显,你会想先检查数据库是否存在,或者知道这是你第一次运行应用程序

如果您计划发布具有更新数据库的更新,那么您需要在检查数据库存在性之外管理版本


虽然没有直接回答您的问题,但是1到2分钟对于sqlite来说真的非常长。你在做什么?我首先要确保您正确使用事务。插入数据1-2分钟(可能)会导致一个巨大的db文件。

对不起,我还不能添加任何注释,这更合适


虽然不是直接回答你的问题,但1到2分钟是最好的 非常非常渴望sqlite。你在做什么?我会先做 确保正确使用事务。插入数据1-2分钟 将(可能)导致一个巨大的数据库文件

或者,我不得不使用预填充数据库的问题与较大的.sq文件(每个表的插入文本超过30 MB)有关,SqlDeLight会在不显示错误消息的情况下无声地中断生成


您需要将db文件放在android上的assets中,然后放在android上的bundle中 并在初始化之前将其复制到各自的文件夹中 我很高兴

必须从android和ios上的资源中加载db让人感觉很不舒服 这意味着共享项目将不是唯一一个 数据已初始化

Kotlin多平台库解决了共享模块中数据库的单一源问题。它对KMM的作用与Android和iOS的作用相同

不幸的是,库的示例中几乎没有介绍使用此功能。我向预期的类DatabaseDriverFactory添加了第二个方法(getDriver),以打开准备好的数据库,并在平台上实现了它。例如,对于androidMain:

actual class DatabaseDriverFactory(private val context: Context) {
    actual fun createDriver(schema: SqlDriver.Schema, fileName: String): SqlDriver {
        return AndroidSqliteDriver(schema, context, fileName)
    }

    actual fun getDriver(schema: SqlDriver.Schema, fileName: String): SqlDriver {
        val database: File = context.getDatabasePath(fileName)

        if (!database.exists()) {
            val inputStream = context.resources.openRawResource(MR.files.dbfile.rawResId)
            val outputStream = FileOutputStream(database.absolutePath)

            inputStream.use { input: InputStream ->
                outputStream.use { output: FileOutputStream ->
                    input.copyTo(output)
                }
            }
        }

        return AndroidSqliteDriver(schema, context, fileName)
    }
}

MR.files.fullDb是库生成的类中的FileResource,它与位于commonMain模块的resources/MR/files目录中的文件名相关联。It属性rawrist表示平台端资源ID。

我正在尝试kotlin multiplatform,我有一个搜索应用程序,在本地数据库上有一本书,所有唯一的单词+单词映射到句子和页面,这对sqlight来说非常重要。我在io协同程序上做了一些db init,但希望完全避免db init(很容易:)。下一个最好的方法是能够随意直接在db上运行.sq文件的内容,即独立于表init.sq文件,这可行吗?它将允许我使用基本信息初始化db,并在后台线程上运行init作业的其余部分。我不知道您是否可以运行任意.sq文件,但如果您直接获得sqlite驱动程序的句柄,您可以在资源文件中使用sql语句并运行它们。如果我了解您的用例,您有一个表,其中包含大约2000-5000个插入(单词列表),还有一个表包含50k-100k个插入(地图),使用快速网络搜索小说大小的统计数据。我将开始尝试简单地提高insert性能(),但假设事务中有insert,则可能无法提高它的速度muchI将尝试降低映射表的复杂性,看看是否可以提高它的速度,因为这将占用大量时间。否则,只需使用一个特殊的init流,在第一次运行应用程序时将db文件从资源复制到db文件夹。显示进度条。那种事。拥有一个部分初始化的数据库似乎很复杂。是的,您正确理解了这个情况。必须从android和ios上的资源中加载db会让人感觉工作量很大,这意味着共享项目将不是唯一初始化数据的地方。我最后要做的是,将所有短数量的插入保留在sqldelight.sq表文件中,并将大插入(本例中的映射)移动到init进程。当应用程序第一次运行时,书籍内容将可供浏览,但在数据库初始化完成之前,搜索功能将不可用,会显示一个进度条来指示这一点。在我的初始化过程中,我将sql插入转换为存储在列表中的kotlin对象,并将其分解为多个文件。在第一次运行时,使用我在mapping table.sq文件中定义的sqldelight insert插入这些映射对象。正如您所提到的,如果我可以获得sqlite驱动程序的句柄,我可以只运行sql语句而不必转换它们,但不确定这是否会显著改善插入所有映射所花费的时间。