2023-01-24 19:08:13 +02:00

125 lines
3.0 KiB
JavaScript

'use strict';
const { getDialect } = require('./dialects');
const createSchemaProvider = require('./schema');
const createMetadata = require('./metadata');
const { createEntityManager } = require('./entity-manager');
const { createMigrationsProvider } = require('./migrations');
const { createLifecyclesProvider } = require('./lifecycles');
const createConnection = require('./connection');
const errors = require('./errors');
const transactionCtx = require('./transaction-context');
// TODO: move back into strapi
const { transformContentTypes } = require('./utils/content-types');
const { validateDatabase } = require('./validations');
class Database {
constructor(config) {
this.metadata = createMetadata(config.models);
this.config = {
connection: {},
settings: {
forceMigration: true,
runMigrations: true,
...config.settings,
},
...config,
};
this.dialect = getDialect(this);
this.dialect.configure();
this.connection = createConnection(this.config.connection);
this.dialect.initialize();
this.schema = createSchemaProvider(this);
this.migrations = createMigrationsProvider(this);
this.lifecycles = createLifecyclesProvider(this);
this.entityManager = createEntityManager(this);
}
query(uid) {
if (!this.metadata.has(uid)) {
throw new Error(`Model ${uid} not found`);
}
return this.entityManager.getRepository(uid);
}
async transaction(cb) {
const notNestedTransaction = !transactionCtx.get();
const trx = notNestedTransaction ? await this.connection.transaction() : transactionCtx.get();
async function commit() {
if (notNestedTransaction) {
await trx.commit();
}
}
async function rollback() {
if (notNestedTransaction) {
await trx.rollback();
}
}
if (!cb) {
return {
commit,
rollback,
get() {
return trx;
},
};
}
return transactionCtx.run(trx, async () => {
try {
const callbackParams = { trx, commit, rollback };
const res = await cb(callbackParams);
await commit();
return res;
} catch (error) {
await rollback();
throw error;
}
});
}
getConnection(tableName) {
const schema = this.connection.getSchemaName();
const connection = tableName ? this.connection(tableName) : this.connection;
return schema ? connection.withSchema(schema) : connection;
}
getSchemaConnection(trx = this.connection) {
const schema = this.connection.getSchemaName();
return schema ? trx.schema.withSchema(schema) : trx.schema;
}
queryBuilder(uid) {
return this.entityManager.createQueryBuilder(uid);
}
async destroy() {
await this.lifecycles.clear();
await this.connection.destroy();
}
}
// TODO: move into strapi
Database.transformContentTypes = transformContentTypes;
Database.init = async (config) => {
const db = new Database(config);
await validateDatabase(db);
return db;
};
module.exports = {
Database,
errors,
};