您当前位置:资讯中心 >开发 >浏览文章

从 SQLlin 的更新看 Kotlin Multiplatform 技术更迭

来源:不详 日期:2024/1/19 9:21:35 阅读量:(0)

作者简介

禹昂,携程移动开发专家,Google 开发者专家(Android),上海 Kotlin User Group 组织者,图书《Kotlin 编程实践》译者。

2022 年底,我们在携程的 Github organization 下开源了 SQLlin,SQLlin 是一款基于 Kotlin DSL 及 KSP 技术的,支持众多平台的 Kotllin Multipllatform SQLite 数据库框架。感兴趣且不了解 SQLlin 的读者可以参考:《携程机票跨端 Kotlin DSL 数据库框架 SQLlin》一文。

SQLlin作为携程机票移动端团队最为完备的一款开源项目,在接近 1 年的时间内经历了不少升级与换血式的更新,也见证了这一年 Kotlin Multiplatform 技术的演进及社区生态的变化。本文将带领大家梳理这些更新,并探求这些更新背后所涉及到的 Kotlin Multiplatform 技术栈在这一年来的更迭与进化。

一、重写 native 驱动层

我们先来回顾一下最初的 SQLlin 架构图:

图片

最初,SQLlin 在 Kotlin/Native 平台上基于开源项目 SQLiter(见参考链接 1),目的是避免重复造轮子。虽然 SQLliter 是来自 Touchlab的优秀开源项目,但最近一年维护更新缓慢。在本文撰写时,SQLiter 于 2023 年 11 月发布了 1.3.0 和 1.3.1 两个版本(1.3.1升级到了 Kotlin 1.9.21,用于修复 1.9.20 的 Kotlin/Native 库版本号相关的问题)。但在这之前的版本,即 1.2.1 发布于 2022年 8 月,基于 Kotlin 1.6.20,一年以上没有更新。对于 2023 年的项目来说,1.6.20 过于老旧。老旧的版本导致了如下一些问题。

1.1 Targets 更新维护不及时

Kotlin 在 1.8.20 版本废弃了一众 32 位 Kotlin/Native targets(目标平台),包括:iosArm32、watchosX86、wasm32、mingwX86、linuxArm32Hfp、linuxMips32、linuxMipsel32。这些目标平台几乎已经完全被淘汰,市面上已经极少有可以运行这些targets 的设备,继续支持已无意义。因此 Kotlin 决定将这些 targets 标记为“deprecated”,并在 1.9.20 版本将它们完全移除。

这些即将被移除的 targets 中,iosArm32、watchosX86、mingwX86 受到 SQLiter 及 SQLlin 的支持。由于 SQLiter 不更新版本,所以这些 targets 将继续存在于 SQLiter 当中,虽然 sqllin-driver 可以在上层移除对这些平台的支持,但长久来说由于编译器版本的更迭,仍然不是最佳做法。

如果说在 sqllin-driver 中移除对旧编译目标的支持可以暂时解决“废弃旧 targets 不及时”的问题,那么“对新 targets 的支持”则无计可施。

Kotlin 在 1.8.0 版本开始支持 watchosDeviceArm64 新目标平台,对应于全新的 64 位 Apple Watch 设备。虽然可以预见使用 Kotlin Multiplatform 技术开发 Apple Watch 应用的开发者不会很多,但 SQLlin 原本支持所有的 watchOS 相关 targets,不支持最新的 Arm64 架构并不合理。由于 SQLiter 不支持 watchosDeviceArm64,因此 SQLlin 也无法支持。

1.2 Bug 无法及时修复

在 SQL 中我们会遇到一个常见的用法——join,在 join 查询时遇到两个表拥有相同名字的列也是常见现象。在 SQLiter的原始实现中,后查询出来的同名列值会覆盖掉先查询出来的同名列值:

override val columnNames: Map<String, Int> by lazy {
    val map = HashMap<String, Int>(this.columnCount)
    for (i in 0 until columnCount) {
        val key = columnName(i)
        if (map.containsKey(key)) {
            var index = 1
            val basicKey = "$key&JOIN"
            var finalKey = basicKey + index
            while (map.containsKey(finalKey)) {
                finalKey = basicKey + ++index
            }
            map[finalKey] = i
        } else {
            map[key] = i
        }
    }
    map
}
关键字:
声明:我公司网站部分信息和资讯来自于网络,若涉及版权相关问题请致电(63937922)或在线提交留言告知,我们会第一时间屏蔽删除。
有价值
0% (0)
无价值
0% (10)

分享转发:

发表评论请先登录后发表评论。愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。