From 4d5a473c53cabda6666f07cbf390268ba9415caf Mon Sep 17 00:00:00 2001 From: Shigma <1700011071@pku.edu.cn> Date: Fri, 28 Jan 2022 15:55:41 +0800 Subject: [PATCH] fix(mongo): create initial values --- plugins/database/mongo/src/index.ts | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/plugins/database/mongo/src/index.ts b/plugins/database/mongo/src/index.ts index 0f0d6c7d08..22e446cba5 100644 --- a/plugins/database/mongo/src/index.ts +++ b/plugins/database/mongo/src/index.ts @@ -1,5 +1,5 @@ import { MongoClient, Db, MongoError, IndexDescription } from 'mongodb' -import { Context, Database, Tables, makeArray, Schema, pick, omit, Query, Model, Dict, noop, KoishiError } from 'koishi' +import { Context, Database, Tables, makeArray, Schema, pick, omit, Query, Model, Dict, noop, KoishiError, isNullable } from 'koishi' import { URLSearchParams } from 'url' import { executeUpdate, executeEval } from '@koishijs/orm-utils' import { transformQuery, transformEval } from './utils' @@ -61,11 +61,9 @@ class MongoDatabase extends Database { return this.client.close() } - /** synchronize table schema */ - private async _syncTable(name: string) { - await this._tableTasks[name] - const coll = await this.db.createCollection(name).catch(() => this.db.collection(name)) + private async _createIndexes(name: string) { const { primary, unique } = this.ctx.model.config[name] + const coll = this.db.collection(name) const newSpecs: IndexDescription[] = [] const oldSpecs = await coll.indexes() ;[primary, ...unique].forEach((keys, index) => { @@ -84,6 +82,24 @@ class MongoDatabase extends Database { await coll.createIndexes(newSpecs) } + private async _createFields(name: string) { + const { fields } = this.ctx.model.config[name] + const coll = this.db.collection(name) + await Promise.all(Object.keys(fields).map((key) => { + if (isNullable(fields[key].initial)) return + return coll.updateMany({ [key]: { $exists: false } }, { $set: { [key]: fields[key].initial } }) + })) + } + + /** synchronize table schema */ + private async _syncTable(name: string) { + await this._tableTasks[name] + await Promise.all([ + this._createIndexes(name), + this._createFields(name), + ]) + } + private _createFilter(name: string, query: Query) { return transformQuery(this.ctx.model.resolveQuery(name, query)) } @@ -114,6 +130,7 @@ class MongoDatabase extends Database { async get(name: TableType, query: Query, modifier: Query.Modifier) { const filter = this._createFilter(name, query) if (!filter) return [] + await this._tableTasks[name] let cursor = this.db.collection(name).find(filter) const { fields, limit, offset = 0, sort } = Query.resolveModifier(modifier) cursor = cursor.project({ _id: 0, ...Object.fromEntries((fields ?? []).map(key => [key, 1])) })