79 lines
2.2 KiB
TypeScript
79 lines
2.2 KiB
TypeScript
import type { ApplicationService } from '@adonisjs/core/types'
|
|
import { Db, MongoClient } from 'mongodb'
|
|
|
|
declare module '@adonisjs/core/types' {
|
|
interface ContainerBindings {
|
|
mongodb: Db
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Singleton reference to the MongoDB Db instance.
|
|
* Set during provider boot, used synchronously by BaseModel.
|
|
*/
|
|
let dbInstance: Db | null = null
|
|
|
|
export function getMongoDb(): Db {
|
|
if (!dbInstance) {
|
|
throw new Error('MongoDB is not connected. Ensure MongodbProvider has booted.')
|
|
}
|
|
return dbInstance
|
|
}
|
|
|
|
export default class MongodbProvider {
|
|
private client: MongoClient | null = null
|
|
|
|
constructor(protected app: ApplicationService) {}
|
|
|
|
async boot() {
|
|
const config = await import('#config/database')
|
|
const { uri, dbName } = config.default
|
|
|
|
this.client = new MongoClient(uri, {
|
|
monitorCommands: true,
|
|
serverSelectionTimeoutMS: 5000,
|
|
})
|
|
|
|
await this.client.connect()
|
|
const db = this.client.db(dbName)
|
|
|
|
dbInstance = db
|
|
this.app.container.bindValue('mongodb', db)
|
|
|
|
// Run pending MongoDB migrations automatically at boot
|
|
const { MigratorRunner } = await import('../database/mongo_migrator.js')
|
|
const migrationsPath = this.app.makePath('database/mongo_migrations')
|
|
const migrator = new MigratorRunner(db, migrationsPath)
|
|
const ran = await migrator.run().catch((err: Error) => {
|
|
console.warn(`[MongoMigrator] Failed to run migrations: ${err.message}`)
|
|
return [] as string[]
|
|
})
|
|
if (ran.length > 0) {
|
|
console.info(`[MongoMigrator] Applied ${ran.length} migration(s): ${ran.join(', ')}`)
|
|
} else {
|
|
console.info('[MongoMigrator] Database is up to date.')
|
|
}
|
|
|
|
// Verify cwmp_exchanges indexes after boot
|
|
const { verifyIndexesAtStartup } = await import('#services/exchange_index_checker')
|
|
await verifyIndexesAtStartup(db, {
|
|
warn: (msg: string) => console.warn(msg),
|
|
info: (msg: string) => console.info(msg),
|
|
}).catch((err) => {
|
|
console.warn(`[ExchangeIndexCheck] Failed to verify indexes: ${(err as Error).message}`)
|
|
})
|
|
}
|
|
|
|
async shutdown() {
|
|
if (this.client) {
|
|
try {
|
|
await this.client.close()
|
|
} catch {
|
|
// Connection may already be closed
|
|
}
|
|
this.client = null
|
|
dbInstance = null
|
|
}
|
|
}
|
|
}
|