zing-orm
Version:
420 lines • 36.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MssqlRepository = void 0;
const RepositoryParams_1 = require("../types/RepositoryParams");
const JoiUtils_1 = require("../../util/JoiUtils");
const CommonTools_1 = require("../../util/CommonTools");
const globals_1 = require("../../util/globals");
const knex_1 = require("knex");
const oracledb = require('oracledb');
const _ = require('lodash');
var Request = require('tedious').Request;
var TYPES = require('tedious').TYPES;
//todo Entity @Column
const MssqlTypes = {
Number: TYPES.Numeric,
String: TYPES.VarChar,
Date: TYPES.DateTime,
};
/**
* Entity manager supposed to work with any entity, automatically find its repository and call its methods,
* whatever entity type are you passing.
*/
class MssqlRepository {
// -------------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------------
constructor(_connection, _entity) {
// super(async () => {
try {
if (!_entity) {
throw Error(`constructor params::_entity can not be ${JSON.stringify(_entity)} !!!`);
}
this.connection = _connection;
this.queryBuilder = (0, knex_1.knex)({ client: 'mssql' });
this.entity = _entity;
this.tableName = (0, globals_1.findTableName)(_entity);
}
catch (err) {
//todo
console.error("初始化 MssqlRepository Class 失败!!!", err);
}
// })
}
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
async executeSql(params) {
try {
await JoiUtils_1.JoiUtils.checkParams(RepositoryParams_1.ExecuteSqlParamsSchema, params);
return await MssqlRepository.executeSqlRaw(this.connection, params);
}
catch (err) {
console.log("executeSql error:", err);
}
}
static async executeSqlRaw(connection, params) {
return new Promise(async (resolve, reject) => {
try {
await JoiUtils_1.JoiUtils.checkParams(RepositoryParams_1.ExecuteSqlParamsSchema, params);
var { sql, binds = {}, options = {} } = params;
console.log("executeSqlRaw params: ", sql, binds, options);
let rows = [];
let request = new Request(sql, (err, rowCount) => {
if (err) {
reject(err);
}
let result = {
rowCount,
rows
};
console.log("executeSqlRaw Query results: ");
console.dir(result);
resolve(result);
});
if (JSON.stringify(binds) !== '{}') {
for (var key in binds) {
console.log("addParameter: p" + key + " = " + binds[key]);
request.addParameter(`p${key}`, MssqlTypes[CommonTools_1.CommonTools.getClass(binds[key])], binds[key]);
}
}
request.on('row', function (row) {
let newRow = _.reduce(row, function (a, k) {
// console.log("_column: ", _column)
a[k.metadata.colName] = k.value;
return a;
}, {});
rows.push(newRow);
});
connection.execSql(request);
}
catch (err) {
console.log("executeSqlRaw error:", err);
}
});
}
// -------------------------------------------------------------------------
// Protected Methods
// -------------------------------------------------------------------------
/**
* Find with pagination and condition.
* - cant use findAndCount for both params
* - use createQueryBuilder
* @param params 参数
* @param params.current 页码
* @param params.pageSize 页面条数
* @param params.sort 排序
* @param dataFunc 数据处理函数
*/
//todo add filter, knex
async getPage(params) {
try {
await JoiUtils_1.JoiUtils.checkParams(RepositoryParams_1.GetPageParamsSchema, params);
let { current, pageSize, options } = params;
let sql = '';
let count_sql = '';
//todo add sql builder and make sure entity.name is not undefined
if (!!options && !!options.schema) {
sql = `SELECT * FROM (SELECT A.*, ROWNUM AS MY_RNUM FROM ( SELECT * FROM "${options.schema}"."${this.tableName}") A
WHERE ROWNUM <= :maxnumrows + :offset) WHERE MY_RNUM > :offset`;
count_sql = `SELECT count(id) FROM "${options.schema}"."${this.tableName}"`;
}
else {
sql = `SELECT * FROM (SELECT A.*, ROWNUM AS MY_RNUM FROM ( SELECT * FROM "${this.tableName}") A
WHERE ROWNUM <= :maxnumrows + :offset) WHERE MY_RNUM > :offset`;
count_sql = `SELECT count(id) FROM "${this.tableName}"`;
}
const result1 = await this.executeSql({
sql,
binds: { offset: (current - 1) * pageSize, maxnumrows: pageSize },
options: { prefetchRows: pageSize + 1, fetchArraySize: pageSize }
});
const result2 = await this.executeSql({ sql: count_sql });
const total = result2.rows[0]['COUNT(ID)'];
return {
// Optional
totalPage: Math.ceil(total / pageSize),
current,
pageSize,
// Required
total,
list: result1.rows
};
}
catch (err) {
console.error("MssqlRepository getPage 失败!!!", err);
throw Error(`MssqlRepository getPage 失败!!!, 错误: ${err}`);
}
}
/**
* get documents by filter of collection
* @param {object} _params - params object
* @param {object} _params.filter - filter of attrs.
* @param {object} _params.like - the object to like the documents to get from the collection
* @param {array} _params.sorts - array of sort str for attrs.
* @param {object} _params.options - query options, e.g. keepAttrs-res attrs; hasEdge-edge res;
* @return {AqlQuery} - interface AqlQuery by arangodb
*/
async getsByFilter(params) {
try {
await JoiUtils_1.JoiUtils.checkParams(RepositoryParams_1.GetsByFilterParamsSchema, params);
let { filter, options } = params;
let filterTemp = Object.assign({}, filter);
// let { filter, sorts, options } = params;
let tempQuery = this.queryBuilder(this.tableName);
for (const key in filterTemp) {
const data = filterTemp[key];
if (Array.isArray(data)) {
// 数组参数,则‘in’
tempQuery = tempQuery.whereIn(key, data);
delete filterTemp[key];
}
else if (!!data && Object.prototype.toString.call(data) === '[object Object]') {
//todo 暂时不支持
/**
* 对象参数结构{opr, value}
* 支持:==, !=, <, <=, >, >=, IN, NOT IN, LIKE, =~, !~
* 注意: typeof null === 'object'
* 增加:opr = 'POSITION' 时需要处理数组属性的查询参数
*/
tempQuery.where(`${key}`, data.opr, data.value);
delete filterTemp[key];
}
}
if (Object.keys(filterTemp).length !== 0) {
tempQuery = tempQuery.where(Object.assign({}, filterTemp));
}
if (!!options && !!options.schema) {
tempQuery = tempQuery.withSchema(options.schema);
}
if (!!options && !!options.keepAttrs) {
tempQuery = tempQuery.column(options.keepAttrs).select();
}
else {
tempQuery = tempQuery.select('*');
}
const query = tempQuery.toSQL().toNative();
console.log("getsByFilter query: ", query);
const result = await this.executeSql({
sql: query.sql,
binds: query.bindings,
});
return result.rows;
}
catch (err) {
console.error("MssqlRepository getsByFilter 失败!!!", err);
throw Error(`MssqlRepository getsByFilter 失败!!!, 错误: ${err}`);
}
}
/**
* update document by _id && newObj from collection
* @param {object} _params - the _id of the document
* @param {string} _params.filter - the _id of the document
* @param {object} _params.newObj - the newObj of the document
* @return {AqlQuery} - interface AqlQuery by arangodb
*/
async updatesByFilter(params) {
try {
await JoiUtils_1.JoiUtils.checkParams(RepositoryParams_1.UpdatesByFilterParamsSchema, params);
let { filter, newObj, options } = params;
let filterTemp = Object.assign({}, filter);
//todo 检查Entity attributes
let newObjTemp = Object.assign({}, newObj);
// let { filter, sorts, options } = params;
let tempQuery = this.queryBuilder(this.tableName);
for (const key in filterTemp) {
const data = filterTemp[key];
if (Array.isArray(data)) {
// 数组参数,则‘in’
tempQuery = tempQuery.whereIn(key, data);
delete filterTemp[key];
}
else if (!!data && Object.prototype.toString.call(data) === '[object Object]') {
//todo 暂时不支持
/**
* 对象参数结构{opr, value}
* 支持:==, !=, <, <=, >, >=, IN, NOT IN, LIKE, =~, !~
* 注意: typeof null === 'object'
* 增加:opr = 'POSITION' 时需要处理数组属性的查询参数
*/
tempQuery.where(`${key}`, data.opr, data.value);
delete filterTemp[key];
}
}
if (Object.keys(filterTemp).length !== 0) {
tempQuery = tempQuery.where(Object.assign({}, filterTemp));
}
if (!!options && !!options.schema) {
tempQuery = tempQuery.withSchema(options.schema);
}
if (!!options && !!options.returns) {
tempQuery = tempQuery.returning(options.returns);
}
const query = tempQuery.update(Object.assign({}, newObjTemp)).toSQL().toNative();
let bindingsObj = {};
for (let i = 0; i < query.bindings.length; i++) {
if (typeof query.bindings[i] === 'object' && query.bindings[i].constructor.name === 'ReturningHelper') {
// bindingsObj[i] = {
// [query.bindings[i].columnName]: { dir: oracledb.BIND_OUT }
// };
query.sql = _.replace(query.sql, `:${i + 1}`, `:${query.bindings[i].columnName}`);
//todo 通过Entity 获取 返回字段的变量类型 用以生成 outBinds type
bindingsObj[query.bindings[i].columnName + ''] = { dir: oracledb.BIND_OUT };
}
else {
bindingsObj[i + 1] = query.bindings[i];
}
}
// console.log('bindingsObj: ', bindingsObj);
console.log("updatesByFilter query: ", query);
const result = await this.executeSql({
sql: query.sql,
binds: bindingsObj,
options: { autoCommit: true }
});
return result.rows;
}
catch (err) {
console.error("MssqlRepository updatesByFilter 失败!!!", err);
throw Error(`MssqlRepository updatesByFilter 失败!!!, 错误: ${err}`);
}
}
async save(params) {
try {
await JoiUtils_1.JoiUtils.checkParams(RepositoryParams_1.SaveParamsSchema, params);
let { obj, options } = params;
//todo 检查Entity attributes
let tempQuery = this.queryBuilder(this.tableName);
if (!!options && !!options.schema) {
tempQuery = tempQuery.withSchema(options.schema);
}
if (!!options && !!options.returns) {
tempQuery = tempQuery.returning(options.returns);
}
const query = tempQuery.insert(obj).toSQL().toNative();
let bindingsObj = {};
for (let i = 0; i < query.bindings.length; i++) {
if (typeof query.bindings[i] === 'object' && query.bindings[i].constructor.name === 'ReturningHelper') {
// bindingsObj[i] = {
// [query.bindings[i].columnName]: { dir: oracledb.BIND_OUT }
// };
query.sql = _.replace(query.sql, `:${i + 1}`, `:${query.bindings[i].columnName}`);
bindingsObj[query.bindings[i].columnName + ''] = { dir: oracledb.BIND_OUT };
}
else {
bindingsObj[i + 1] = query.bindings[i];
}
}
const result = await this.executeSql({
sql: query.sql,
binds: bindingsObj,
options: { autoCommit: true }
});
return result.rows;
}
catch (err) {
console.error("MssqlRepository save 失败!!!", err);
throw Error(`MssqlRepository save 失败!!!, 错误: ${err}`);
}
}
async deletesByFilter(params) {
try {
await JoiUtils_1.JoiUtils.checkParams(RepositoryParams_1.DeletesByFilterParamsSchema, params);
let { filter, options } = params;
let filterTemp = Object.assign({}, filter);
//todo 检查Entity attributes
// let { filter, sorts, options } = params;
let tempQuery = this.queryBuilder(this.tableName);
for (const key in filterTemp) {
const data = filterTemp[key];
if (Array.isArray(data)) {
// 数组参数,则‘in’
tempQuery = tempQuery.whereIn(key, data);
delete filterTemp[key];
}
else if (!!data && Object.prototype.toString.call(data) === '[object Object]') {
//todo 暂时不支持
/**
* 对象参数结构{opr, value}
* 支持:==, !=, <, <=, >, >=, IN, NOT IN, LIKE, =~, !~
* 注意: typeof null === 'object'
* 增加:opr = 'POSITION' 时需要处理数组属性的查询参数
*/
tempQuery.where(`${key}`, data.opr, data.value);
}
}
if (Object.keys(filterTemp).length !== 0) {
tempQuery = tempQuery.where(Object.assign({}, filterTemp));
}
if (!!options && !!options.schema) {
tempQuery = tempQuery.withSchema(options.schema);
}
//todo return can't work
// if (!!options && !!options.returns) {
// tempQuery = tempQuery.returning(options.returns)
// }
const query = tempQuery.del().toSQL().toNative();
let bindingsObj = {};
for (let i = 0; i < query.bindings.length; i++) {
if (typeof query.bindings[i] === 'object' && query.bindings[i].constructor.name === 'ReturningHelper') {
query.sql = _.replace(query.sql, `:${i + 1}`, `:${query.bindings[i].columnName}`);
bindingsObj[query.bindings[i].columnName + ''] = { dir: oracledb.BIND_OUT };
}
else {
bindingsObj[i + 1] = query.bindings[i];
}
}
if (!!options && !!options.returns && Array.isArray(options.returns)) {
let returningStr = ' returning';
for (let i = 0; i < options.returns.length; i++) {
returningStr = returningStr + ` "${options.returns[i]}" INTO :${options.returns[i]}`;
bindingsObj[options.returns[i] + ''] = { dir: oracledb.BIND_OUT };
}
query.sql = query.sql + returningStr;
}
// console.log('bindingsObj: ', bindingsObj);
const result = await this.executeSql({
sql: query.sql,
binds: bindingsObj,
options: { autoCommit: true }
});
return result.rows;
}
catch (err) {
console.error("MssqlRepository deletesByFilter 失败!!!", err);
throw Error(`MssqlRepository deletesByFilter 失败!!!, 错误: ${err}`);
}
}
async executeProcedure(params) {
try {
await JoiUtils_1.JoiUtils.checkParams(RepositoryParams_1.ExecuteProcedureParamsSchema, params);
let { binds, options } = params;
let bindsStr = '';
for (var key in binds) {
bindsStr = bindsStr + ` :${key},`;
}
bindsStr = bindsStr.slice(0, -1);
console.log('bindsStr:', bindsStr);
var schema = '';
if (!!options && !!options.schema) {
schema = options.schema;
}
const query = this.queryBuilder.raw(`BEGIN
"${schema}"."${this.tableName}"(${bindsStr});
COMMIT;
END;`).toSQL().toNative();
console.log('query: ', query);
const result = await this.executeSql({
sql: query.sql,
binds: binds
});
return result.rows;
}
catch (err) {
console.error("MssqlRepository executeProcedure 失败!!!", err);
throw Error(`MssqlRepository executeProcedure 失败!!!, 错误: ${err}`);
}
}
}
exports.MssqlRepository = MssqlRepository;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTXNzcWxSZXBvc2l0b3J5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiTXNzcWxSZXBvc2l0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLGdFQWVtQztBQUNuQyxrREFBK0M7QUFDL0Msd0RBQXFEO0FBQ3JELGdEQUFtRDtBQUNuRCwrQkFBNEI7QUFDNUIsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ3JDLE1BQU0sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUM1QixJQUFJLE9BQU8sR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsT0FBTyxDQUFDO0FBQ3pDLElBQUksS0FBSyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxLQUFLLENBQUM7QUFFckMscUJBQXFCO0FBQ3JCLE1BQU0sVUFBVSxHQUFHO0lBQ2YsTUFBTSxFQUFFLEtBQUssQ0FBQyxPQUFPO0lBQ3JCLE1BQU0sRUFBRSxLQUFLLENBQUMsT0FBTztJQUNyQixJQUFJLEVBQUUsS0FBSyxDQUFDLFFBQVE7Q0FDdkIsQ0FBQTtBQUdEOzs7R0FHRztBQUNILE1BQWEsZUFBZTtJQWtCeEIsNEVBQTRFO0lBQzVFLGNBQWM7SUFDZCw0RUFBNEU7SUFDNUUsWUFBWSxXQUFnQixFQUFFLE9BQVk7UUFDdEMsc0JBQXNCO1FBQ3RCLElBQUk7WUFDQSxJQUFJLENBQUMsT0FBTyxFQUFFO2dCQUNWLE1BQU0sS0FBSyxDQUFDLDBDQUEwQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUN4RjtZQUNELElBQUksQ0FBQyxVQUFVLEdBQUcsV0FBVyxDQUFDO1lBQzlCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBQSxXQUFJLEVBQUMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUM5QyxJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQztZQUN0QixJQUFJLENB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