koishijs / koishi

Cross-platform chatbot framework made with love
https://koishi.chat
MIT License
4.37k stars 239 forks source link

Feature: 实现一个统一的接口存放插件的一些零碎数据 #887

Closed Seidko closed 1 year ago

Seidko commented 1 year ago

Describe the problem related to the feature request

目前的 koishi 插件只能在数据库中或者自己创建一个本地文件来存储一些全局的kv变量:比如marry插件,需要记录上次清除结婚数据的时间,但是存在数据库中又显得很没有必要:

image

看!专门创建了一个表只是为了存储这个latestCleanUpTime 而且代码也显得很冗长:

interface MarryData {
  id: number
  latestCleanUpTime: Date
}

declare module 'koishi' {
  interface Tables {
    marry_data: MarryData
  }
}

export function apply(ctx: Context, config: Config) {
  ctx.model.extend('marry_data', {
    id: 'unsigned',
    latestCleanUpTime: 'timestamp',
  })
  // ...
}

而且数据库操作也很麻烦,如果用本地文件存储的话就更不用说了,会造成管理混乱,甚至插件冲突等问题。

有人可能会说:可以存在配置文件里呀?是可以的,但是配置文件是存储插件设置的地方,而不是存储插件数据的地方,配置文件不应该被滥用,应该有一个专门的地方来存储这些零碎的数据。

所以可不可以有一种方法来存储这些零碎的、全局的变量呢?

Describe the solution you'd like

解决方法一

创建一个新的,统一的yaml(或者json)来存储这些kv数据,像这样:

plugins:
  marry:
    latestCleanUpTime: 0
  other-plugin:
    xxx: str
  # ...

然后通过ctx.data来get和set这些数据

解决方法二

ctx.database提供一个 kv db 简化接口,如:

declare module 'koishi' {
  interface Data {
    latestCleanUpTime: Date
  }
}

ctx.database.setData('latestCleanUpTime', new Date())
const latestCleanUpTime = ctx.database.getData('latestCleanUpTime')
plugins key value
marry latestCleanUpTime 16000000
other-plugin xxx str

跨插件读取数据可以像这样:

// other-plugin
const latestCleanUpTime = ctx.database.getData('latestCleanUpTime', 'marry')
ctx.database.setData('latestCleanUpTime', new Date(), 'marry')

Describe alternatives you've considered

No response

Additional context

欢迎讨论,提供更多的想法~

shigma commented 1 year ago

可以做。

J9UJNGXP`Q)R~5I_$S1 $%U

simon300000 commented 1 year ago

看起来你们甚至需要一个 koishi-plugin- adapter-koishi

TimeBather commented 1 year ago

我觉得能不能可以统一为一个 Storage API,可以统一管理插件的存储位置,然后插件可以自行使用其他方法(比如JSON)管理数据。 I think we can use a unify api which called Storage API . It can manage and assign the storage path for each plugin. And plugins can use other ways (such as json file) to manage their data.

TimeBather commented 1 year ago

我认为仅仅为了临时存储一个数据而引入一个API是不太好的,相反,引入Storage API不仅能解决插件零碎数据存储的问题(他们可以自己解决如何存储这些文件),还能解决一些文件化数据的存储(比如NoneBot插件的插件缓存、Blockly插件用户编辑的文档) I think it's not good to use an API for only storage some misc datas. And the storage API can resolve the problem for misc datas.(Plugin can manage the ways of storage themselves), and it also resolves problems for storaging some file-styled data.(Such as the plugin data cache for nonebot plugin , the user plugin document file for blockly plugin)

TimeBather commented 1 year ago

The example for storage API is:

const storage = ctx.storage.get("plugin-name")
storage.set("/test1.json",{"key":"value"}) // Save and serialize the k-v map
storage.set("/test1.json",[1,2,3,4,5,6]) // Save and serialize the array
storage.set("/publickey.pem",generatedPublicKey) // Save the file data
//......
storage.get("/test1.json",{unserialize:true}); // Config "unserialize" is forcing making sure the data is serialized , otherwise it will throw an error.
storage.get("/publickey.pem");

storage.path(); // For example , returns /path/to/koishi/data/plugin-name
storage.path("/child-dir"); // For example , returns /path/to/koishi/data/plugin-name/child-dir

storage.isFile()
storage.isDirectory() // or storage.isDir()

storage.delete()
ghost commented 1 year ago

我觉得可以用缓存来存取这些数据,存取速度快也方便。我使用的是redis,官方的@koishijs/plugin-database-memory应该也是个不错的选择

shigma commented 1 year ago

现在已经有标准化的缓存服务了:https://cache.koishi.chat

Pluckypan commented 1 year ago

现在已经有标准化的缓存服务了:https://cache.koishi.chat

文档你没有发布吧,访问不了,看到项目了 https://github.com/koishijs/cache/blob/main/docs/zh-CN/index.md 建议丰富一下使用案例,跟 quick start 的形式一样

Pluckypan commented 1 year ago

现在已经有标准化的缓存服务了:https://cache.koishi.chat

文档你没有发布吧,访问不了,看到项目了 https://github.com/koishijs/cache/blob/main/docs/zh-CN/index.md 建议丰富一下使用案例,跟 quick start 的形式一样

image