Skip to content

Commit

Permalink
feat: use _id directly to store table name
Browse files Browse the repository at this point in the history
  • Loading branch information
Hieuzest committed Oct 11, 2024
1 parent d22371c commit 86b1b8f
Showing 1 changed file with 28 additions and 27 deletions.
55 changes: 28 additions & 27 deletions packages/mongo/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import enUS from './locales/en-US.yml'
const tempKey = '__temp_minato_mongo__'

interface TableMeta {
table: string
_id: string
virtual?: boolean
migrate?: boolean
autoInc?: number
Expand Down Expand Up @@ -136,59 +136,60 @@ export class MongoDriver extends Driver<MongoDriver.Config> {
const coll = this.db.collection(table)
const bulk = coll.initializeOrderedBulkOp()
const virtualKey = this.getVirtualKey(table)
const meta = await this.db.collection<TableMeta>('_fields').findOne({ table })
if (!meta?.fields) {
const metaTable = this.db.collection<TableMeta>('_fields')
const meta = { _id: table }, found = await metaTable.findOne(meta)
if (!found?.fields) {
this.logger.info('initializing fields for table %s', table)
await this.db.collection('_fields').updateOne({ table }, { $set: { fields: Object.keys(fields) } }, { upsert: true })
await metaTable.updateOne(meta, { $set: { fields: Object.keys(fields) } }, { upsert: true })
return
}
for (const key in fields) {
if (virtualKey === key) continue
const { initial, legacy = [] } = fields[key]!
if (!Field.available(fields[key])) continue
if (meta.fields.includes(key)) continue
if (found.fields.includes(key)) continue
this.logger.info('auto migrating field %s for table %s', key, table)

const oldKey = meta.fields.find(field => legacy.includes(field))
const oldKey = found.fields.find(field => legacy.includes(field))
if (oldKey) {
remove(meta.fields, oldKey)
meta.fields.push(key)
remove(found.fields, oldKey)
found.fields.push(key)
bulk.find({ [oldKey]: { $exists: true } }).update({ $rename: { [oldKey]: key } })
} else {
meta.fields.push(key)
found.fields.push(key)
bulk.find({}).update({ $set: { [key]: initial ?? null } })
}
}
if (bulk.batches.length) {
await bulk.execute()
await this.db.collection('_fields').updateOne({ table }, { $set: { fields: meta.fields } })
await metaTable.updateOne(meta, { $set: { fields: found.fields } })
}
}

private async _migrateVirtual(table: string) {
const { primary, fields: modelFields } = this.model(table)
const { primary, fields } = this.model(table)
if (Array.isArray(primary)) return
const fields = this.db.collection<TableMeta>('_fields')
const meta = await fields.findOne({ table })
let virtual = !!meta?.virtual
const metaTable = this.db.collection<TableMeta>('_fields')
const meta = { _id: table }, found = await metaTable.findOne(meta)
let virtual = !!found?.virtual
const useVirtualKey = !!this.getVirtualKey(table)
// If _fields table was missing for any reason
// Test the type of _id to get its possible preference
if (!meta) {
if (!found) {
const doc = await this.db.collection(table).findOne()
if (doc) {
virtual = typeof doc._id !== 'object' || (typeof primary === 'string' && modelFields[primary]?.deftype === 'primary')
virtual = typeof doc._id !== 'object' || (typeof primary === 'string' && fields[primary]?.deftype === 'primary')
} else {
// Empty collection, just set meta and return
await fields.updateOne({ table }, { $set: { virtual: useVirtualKey } }, { upsert: true })
await metaTable.updateOne(meta, { $set: { virtual: useVirtualKey } }, { upsert: true })
this.logger.info('successfully reconfigured table %s', table)
return
}
}
if (virtual === useVirtualKey) return
this.logger.info('start migrating table %s', table)

if (meta?.migrate && await this.db.listCollections({ name: '_migrate_' + table }).hasNext()) {
if (found?.migrate && await this.db.listCollections({ name: '_migrate_' + table }).hasNext()) {
this.logger.info('last time crashed, recover')

Check warning on line 193 in packages/mongo/src/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/mongo/src/index.ts#L193

Added line #L193 was not covered by tests
} else {
await this.db.dropCollection('_migrate_' + table).catch(noop)
Expand All @@ -199,11 +200,11 @@ export class MongoDriver extends Driver<MongoDriver.Config> {
{ $unset: ['_temp_id', ...useVirtualKey ? [primary] : []] },
{ $out: '_migrate_' + table },
]).toArray()
await fields.updateOne({ table }, { $set: { migrate: true } }, { upsert: true })
await metaTable.updateOne(meta, { $set: { migrate: true } }, { upsert: true })
}
await this.db.dropCollection(table).catch(noop)
await this.db.renameCollection('_migrate_' + table, table)
await fields.updateOne({ table },
await metaTable.updateOne(meta,
{ $set: { virtual: useVirtualKey, migrate: false } },
{ upsert: true },
)
Expand All @@ -213,9 +214,9 @@ export class MongoDriver extends Driver<MongoDriver.Config> {
private async _migratePrimary(table: string) {
const { primary, autoInc } = this.model(table)
if (Array.isArray(primary) || !autoInc) return
const fields = this.db.collection('_fields')
const meta = await fields.findOne({ table })
if (!isNullable(meta?.autoInc)) return
const metaTable = this.db.collection<TableMeta>('_fields')
const meta = { _id: table }, found = await metaTable.findOne(meta)
if (!isNullable(found?.autoInc)) return

const coll = this.db.collection(table)
// Primary _id cannot be modified thus should always meet the requirements
Expand All @@ -230,7 +231,7 @@ export class MongoDriver extends Driver<MongoDriver.Config> {
}

const [latest] = await coll.find().sort(this.getVirtualKey(table) ? '_id' : primary, -1).limit(1).toArray()
await fields.updateOne({ table }, {
await metaTable.updateOne(meta, {
$set: { autoInc: latest ? +latest[this.getVirtualKey(table) ? '_id' : primary] : 0, virtual: !!this.getVirtualKey(table) },
}, { upsert: true })
}
Expand Down Expand Up @@ -269,7 +270,7 @@ export class MongoDriver extends Driver<MongoDriver.Config> {
}

async drop(table: string) {
await this.db.collection('_fields').deleteOne({ table }, { session: this.session })
await this.db.collection<TableMeta>('_fields').deleteOne({ _id: table }, { session: this.session })
await this.db.dropCollection(table, { session: this.session })
}

Expand Down Expand Up @@ -412,8 +413,8 @@ export class MongoDriver extends Driver<MongoDriver.Config> {
if (typeof primary === 'string' && autoInc && model.fields[primary]?.deftype !== 'primary') {
const missing = data.filter(item => !(primary in item))
if (!missing.length) return
const doc = await this.db.collection('_fields').findOneAndUpdate(
{ table },
const doc = await this.db.collection<TableMeta>('_fields').findOneAndUpdate(
{ _id: table },
{ $inc: { autoInc: missing.length } },
{ session: this.session, upsert: true },
)
Expand Down

0 comments on commit 86b1b8f

Please sign in to comment.