「随想」关于将本地数据迁移到云端

「随想」关于将本地数据迁移到云端

·

1 min read

我这段时间在做 Tauri 本地应用,目前数据通过状态管理库(zustand) + tauri-plugin-store 持久化到本地文件中,后来我为了安全,做了一个数据导入、导出的功能,但完成后我就觉得不太对劲,好像整个流程上存在问题,我不知道最佳实践是什么样的。

或者可以这样说吧,我现在的数据是持久化到文件的,我想要把他保存在云端(等其他地方),并且支持从这些数据源恢复数据,同时也有数据迁移。

先说一下状态管理库持久化的情况:

{
      name: 'name',
      // 持久化的一些方法
      storage: createJSONStorage(() => appStorage),
      // 最新的版本号
      version: VERSION,
      // 需要持久化的字段
      partialize: (state) => ({ scripts: state.scripts }),
      // 数据迁移函数
      migrate: (persistedState: any, version) => {
          // 持久化数据的版本号,会重复执行这个 migrate 函数直到两个版本号一致
          if (version === 0) {
              // 数据迁移
          return persistedState
          }
          return persistedState
      }
}

// appStore 的实现,用于适配多种数据库
(store) => ({
  getItem: async (name: string): Promise<string | null> => {},
  setItem: async (name: string, value: string): Promise<void> => {},
  removeItem: async (name: string): Promise<void> => {},
})

我的数据不需要维护版本号之类的信息,这些都是 zustand 帮我维护的,所以最终保存到本地的数据大概是这样的:

{
  version: number,
  state: {
    // zustand 实际存的数据
      scripts: []
  }
}

如果要上传,那么肯定是上传 scripts 列表,也就是数据本体,这样拉回数据的时候,可以直接写入 zustand store,但这样做的话,version 就没了,那就分不清楚这个数据是什么版本下上传的了。

如果我带上 version 一起上传,这样数据恢复时,似乎需要我手动去调用 migrate 函数进行迁移。。。


写完找到灵感了,就带上 version 保存,把 migrate 函数提取出去复用,恢复数据的时候通过 restore 函数调用 migrate 进行迁移:

function restore(state, ver) {
    // 确保初始版本号小于或等于目标版本号,避免逻辑错误
    if (ver > VERSION) {
        console.error("云端数据版本号大于最新版");
        return;
    }

    let currentState = state;
    for (let currentVer = ver; currentVer < VERSION; currentVer++) {
        currentState = migrate(currentState, currentVer);
        console.log(`成功迁移到版本 ${currentVer + 1}`);
    }

    // 确保最终版本与预期相符
    if (currentState.version !== VERSION) {
        console.warn("迁移函数不完整");
    } else {
        console.log("数据迁移完成");
    }

    return currentState;
}