typeorm-sharding-repository
Version:
TypeORM Sharding Repository: Enables TypeORM to be utilized in a distributed database environment.
235 lines (234 loc) • 9.87 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ShardingBaseEntity = void 0;
const ObjectUtils_1 = require("typeorm/util/ObjectUtils");
class ShardingBaseEntity {
base() {
return this.constructor;
}
save(options) {
return __awaiter(this, void 0, void 0, function* () {
return this.base().getManager(this).save(this, options);
});
}
remove(options) {
return __awaiter(this, void 0, void 0, function* () {
return this.base().getManager(this).remove(this, options);
});
}
softRemove(options) {
return __awaiter(this, void 0, void 0, function* () {
return this.base().getManager(this).softRemove(this, options);
});
}
recover(options) {
return __awaiter(this, void 0, void 0, function* () {
return this.base().getManager(this).recover(this, options);
});
}
reload() {
return __awaiter(this, void 0, void 0, function* () {
const repo = this.base().getRepository(this);
const id = repo.metadata.getEntityIdMap(this.base());
if (!id)
throw new Error(`Entity doesn't have id-s set, cannot reload entity`);
const reloadedEntity = yield repo.findOneByOrFail(id);
ObjectUtils_1.ObjectUtils.assign(this, reloadedEntity);
});
}
// _______.___________. ___ .___________. __ ______
// / | | / \ | || | / |
// | (----`---| |----` / ^ \ `---| |----`| | | ,----'
// \ \ | | / /_\ \ | | | | | |
// .----) | | | / _____ \ | | | | | `----.
// |_______/ |__| /__/ \__\ |__| |__| \______|
static wrapArray(entities, func) {
return __awaiter(this, void 0, void 0, function* () {
const isArray = Array.isArray(entities);
entities = (isArray ? entities : [entities]);
const result = yield func(entities);
return isArray ? result : result[0];
});
}
static save(entities, options) {
return __awaiter(this, void 0, void 0, function* () {
return this.wrapArray(entities, (list) => Promise.all(list.map((item) => {
return this.getRepository(item).save(this.getRepository(item).create(item), options);
})));
});
}
static create(entities) {
if (!entities)
return this.getRepository({}).create();
const isArray = Array.isArray(entities);
entities = (isArray ? entities : [entities]);
const result = entities.map((item) => this.getRepository(item).create(item));
return isArray ? result : result[0];
}
static remove(entities, options) {
return this.wrapArray(entities, (list) => Promise.all(list.map((item) => this.getRepository(item).remove(item, options))));
}
static softRemove(entities, options) {
return this.wrapArray(entities, (list) => Promise.all(list.map((item) => this.getRepository(item).softRemove(item, options))));
}
////
static update(criteria, partialEntity) {
return __awaiter(this, void 0, void 0, function* () {
return (yield Promise.all(this.getAllRepository().map((repo) => repo.update(criteria, partialEntity)))).reduce((accum, result) => {
accum.raw.push(...(result.raw || []));
accum.affected += Number(result.affected) || 0;
accum.generatedMaps.push(...(result.generatedMaps || []));
return accum;
}, {
raw: [],
affected: 0,
generatedMaps: [],
});
});
}
////
static delete(criteria) {
return __awaiter(this, void 0, void 0, function* () {
return (yield Promise.all(this.getAllRepository().map((repo) => repo.delete(criteria)))).reduce((accum, result) => {
accum.raw.push(...(result.raw || []));
accum.affected += Number(result.affected) || 0;
return accum;
}, {
raw: [],
affected: 0,
});
});
}
////
static count(options) {
return __awaiter(this, void 0, void 0, function* () {
return (yield Promise.all(this.getAllRepository().map((repo) => repo.count(options)))).reduce((total, count) => total + count.valueOf(), 0);
});
}
////
static countBy(where) {
return __awaiter(this, void 0, void 0, function* () {
return (yield Promise.all(this.getAllRepository().map((repo) => repo.countBy(where)))).reduce((total, count) => total + count.valueOf(), 0);
});
}
////
static find(options) {
return __awaiter(this, void 0, void 0, function* () {
return (yield Promise.all(this.getAllRepository().map((repo) => repo.find(options)))).reduce((accum, result) => {
accum.push(...result);
return accum;
}, []);
});
}
////
static findBy(where) {
return __awaiter(this, void 0, void 0, function* () {
return (yield Promise.all(this.getAllRepository().map((repo) => repo.findBy(where)))).reduce((accum, result) => {
accum.push(...result);
return accum;
}, []);
});
}
////
static findAndCount(options) {
return __awaiter(this, void 0, void 0, function* () {
return (yield Promise.all(this.getAllRepository().map((repo) => repo.findAndCount(options)))).reduce((accum, result) => {
accum[0].push(...(result[0] || []));
accum[1] += result[1] || 0;
return accum;
}, [[], 0]);
});
}
////
static findAndCountBy(where) {
return __awaiter(this, void 0, void 0, function* () {
return (yield Promise.all(this.getAllRepository().map((repo) => repo.findAndCountBy(where)))).reduce((accum, result) => {
accum[0].push(...(result[0] || []));
accum[1] += result[1] || 0;
return accum;
}, [[], 0]);
});
}
////
static findByIds(ids) {
return __awaiter(this, void 0, void 0, function* () {
const slices = [];
ids.forEach((id) => {
const dataSource = this.getDataSourceById(id);
let found = slices.find((item) => item[0] === dataSource);
if (!found) {
found = [dataSource, []];
slices.push(found);
}
found[1].push(id);
});
return (yield Promise.all(slices.map(([dataSource, ids]) => dataSource.getRepository(this).findByIds(ids)))).reduce((accum, items) => {
accum.push(...items);
return accum;
}, []);
});
}
////
static findOne(options) {
return __awaiter(this, void 0, void 0, function* () {
return (yield Promise.all(this.getAllRepository().map((repo) => repo.findOne(options)))).find((v) => !!v);
});
}
////
static findOneBy(where) {
return __awaiter(this, void 0, void 0, function* () {
return (yield Promise.all(this.getAllRepository().map((repo) => repo.findOneBy(where)))).find((v) => !!v);
});
}
////
static findOneById(id) {
return this.getDataSourceById(id).getRepository(this).findOneById(id);
}
static shardingManager() {
if (!this._shardingManager || this._shardingManager.destroyed)
this._shardingManager = Reflect.getMetadata('SHARDING_MANAGER', this);
return this._shardingManager;
}
static shardingFunc() {
if (!this._shardingFunc)
this._shardingFunc = Reflect.getMetadata('SHARDING_FUNC', this);
return this._shardingFunc;
}
static shardingFuncById() {
if (!this._shardingFuncById)
this._shardingFuncById = Reflect.getMetadata('SHARDING_FUNC_BY_ID', this);
return this._shardingFuncById;
}
static getAllRepository() {
return this.getAllDataSource().map((item) => item.getRepository(this));
}
static getRepository(entity) {
return this.getDataSource(entity).getRepository(this);
}
static getManager(entity) {
return this.getDataSource(entity).manager;
}
static getAllDataSource() {
return this.shardingManager().dataSources;
}
static getDataSource(entity) {
if (!entity)
throw new Error(`ShardingBaseEntity: Direct DataSource access is not allowed.`);
return this.shardingManager().getDataSource(entity, this.shardingFunc());
}
static getDataSourceById(id) {
if (!id)
throw new Error(`ShardingBaseEntity: Direct DataSource access is not allowed.`);
return this.shardingManager().getDataSourceById(id, this.shardingFuncById());
}
}
exports.ShardingBaseEntity = ShardingBaseEntity;