Skip to content

Commit

Permalink
feat(0.1.0): 发布0.1.0,修复问题
Browse files Browse the repository at this point in the history
  • Loading branch information
ruixiaozi committed Nov 4, 2023
1 parent c2438cf commit 2236765
Show file tree
Hide file tree
Showing 12 changed files with 500 additions and 91 deletions.
14 changes: 13 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,20 @@
> 次版本:每季度发布一次,向下兼容的功能性新增
> 修订版本:每周发布一次(紧急版本随时发布),向下兼容的问题修正
## 0.1.0 [Current]
###### 发布日期:2023-11-04
###### 兼容性:0.1.x

## 0.0.7 [Current]
+ 修复自动transaction方法返回值问题
+ 增加软删除功能
+ 增加多唯一键支持
+ 增加连接前置后置hook
+ connect api从同步改变为异步【不兼容0.0.7及以下版本】
+ 删除autoSync api对外暴露,增加connect的autoSync选项
+ 弃用saveOrUpdate和saveOrUpdateAll,存在关联表bug
+ query增加everyEqOrLike方法

## 0.0.7
###### 发布日期:2023-09-20
###### 兼容性:0.x.x

Expand Down
9 changes: 5 additions & 4 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ export default {
coverageThreshold: {
// 所有文件总的覆盖率要求
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
branches: 70,
functions: 70,
lines: 70,
statements: 70,
},
},
// 用排除法,解决lint-stage增量时的问题
Expand Down Expand Up @@ -38,4 +38,5 @@ export default {
},
],
},
maxWorkers: 1,
};
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "brisk-orm",
"version": "0.0.7",
"version": "0.1.0",
"description": "fast, light-weight, brisk ORM to work in nodejs, support mongodb",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down Expand Up @@ -33,9 +33,9 @@
},
"homepage": "https://github.com/ruixiaozi/brisk-orm#readme",
"dependencies": {
"brisk-ioc": "0.0.7",
"brisk-log": "0.0.7",
"brisk-ts-extends": "0.0.7",
"brisk-ioc": "0.1.0",
"brisk-log": "0.1.0",
"brisk-ts-extends": "0.1.0",
"lodash": "4.17.21",
"mysql2": "3.1.0",
"uuid": "9.0.0"
Expand Down
131 changes: 111 additions & 20 deletions src/core/base.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* eslint-disable id-length */
import { getLogger, LOGGER_LEVEL_E } from 'brisk-log';
import mysql, { QueryOptions } from 'mysql2/promise';
import * as runtime from 'brisk-ts-extends/runtime';
import { Class, isLike } from 'brisk-ts-extends';
import { Class, isLike, PropertiesDes } from 'brisk-ts-extends';
import {
BriskOrmConnectOption,
BriskOrmContext,
Expand All @@ -13,30 +14,94 @@ import {
BriskOrmSelectFunction,
BriskOrmUpdateFunction,
BriskOrmInnerClass,
BRISK_ORM_FOREIGN_ACTION_E,
} from '../types';

export interface BriskOrmHooks {
priority: number;
handler: () => Promise<void> | void;
}

// 保存运行时参数
const globalVal: {
_briskOrmPool?: mysql.Pool,
_briskOrmRegion?: symbol,
_briskOrmBefores?: BriskOrmHooks[],
_briskOrmAfters?: BriskOrmHooks[],
// 全局排除同步的表
_briskOrmAutoSyncExc?: string[],
// 默认false,是否开启同步
_briskOrmEnableAutoSync?: boolean;
// 默认false。设置true开启删除多余表格
_briskOrmEnableDeleteTable?: boolean;
// 默认false。设置true开启更新存在的表格
_briskOrmEenableUpdateTable?: boolean;
// 有id的select方法
_briskOrmSelectFunctions?: Map<string, BriskOrmSelectFunction>;
// 有id的delete方法
_briskOrmDeleteFunctions?: Map<string, BriskOrmDeleteFunction>;
[key: string | symbol | number]: any,
} = globalThis;

if (!globalVal._briskOrmRegion) {
globalVal._briskOrmRegion = Symbol('briskOrm');
}

if (!globalVal._briskOrmBefores) {
globalVal._briskOrmBefores = [];
}

if (!globalVal._briskOrmAfters) {
globalVal._briskOrmAfters = [];
}

if (!globalVal._briskOrmSelectFunctions) {
globalVal._briskOrmSelectFunctions = new Map<string, BriskOrmSelectFunction>();
}
if (!globalVal._briskOrmDeleteFunctions) {
globalVal._briskOrmDeleteFunctions = new Map<string, BriskOrmDeleteFunction>();
}


const logger = getLogger(globalVal._briskOrmRegion);
logger.configure({
// 默认是info级别,可通过配置全局来改变此等级
level: LOGGER_LEVEL_E.info,
});

const sortBy = (hookA: BriskOrmHooks, hookB: BriskOrmHooks) => hookA.priority - hookB.priority;

// 添加钩子
export function addHook(pos: 'before_conn' | 'after_conn', hook: BriskOrmHooks) {
switch (pos) {
case 'before_conn':
globalVal._briskOrmBefores?.push(hook);
break;
case 'after_conn':
globalVal._briskOrmAfters?.push(hook);
break;
default:
break;
}
}


export async function connect(option: BriskOrmConnectOption) {
globalVal._briskOrmEnableAutoSync = option.autoSync.enable;
globalVal._briskOrmEnableDeleteTable = option.autoSync.enableDeleteTable;
globalVal._briskOrmEenableUpdateTable = option.autoSync.enableUpdateTable;
globalVal._briskOrmAutoSyncExc!.concat(option.autoSync.expectTables || []);

export function connect(option: BriskOrmConnectOption) {
globalVal._briskOrmBefores?.sort(sortBy);
for (let beforeHook of globalVal._briskOrmBefores!) {
await Promise.resolve(beforeHook.handler());
}
globalVal._briskOrmPool = mysql.createPool(option);
logger.debug('create globalVal._briskOrmPool', option);
globalVal._briskOrmAfters?.sort(sortBy);
for (let afterHook of globalVal._briskOrmAfters!) {
await Promise.resolve(afterHook.handler());
}
}

export function distory() {
Expand Down Expand Up @@ -75,12 +140,18 @@ export async function startTransaction(): Promise<BriskOrmContext> {
* 自动事务
* @param handler 事务实际业务处理器
* @param transactionName 事务名称,用于表示当前事务
* @param parentCtx 父级ctx,可以传递ctx
*/
export async function transaction(handler: (ctx: BriskOrmContext) => any, transactionName: string) {
const ctx = await startTransaction();
export async function transaction<T>(
handler: (ctx: BriskOrmContext) => T,
transactionName: string,
parentCtx?: BriskOrmContext,
): Promise<T> {
const ctx = parentCtx || await startTransaction();
try {
await Promise.resolve(handler(ctx));
const res = await Promise.resolve(handler(ctx));
await ctx.commit();
return res;
} catch (error) {
await ctx.rollback(transactionName);
throw error;
Expand All @@ -99,8 +170,6 @@ export function query(sql: string, params?: any[], ctx?: BriskOrmContext): Promi
})?.then((res) => res?.[0]);
}

// 保存有id的select方法
const selectFunctions = new Map<string, BriskOrmSelectFunction>();

// 对结果对象的值进行处理
function getValueProperty(value: any, key: string) {
Expand All @@ -122,7 +191,7 @@ async function transEntiry<T>(value: any, Target: Class<T>, mapping: BriskOrmEnt
(resTarget as any)[clsProp] = propertyValue;
}
} else {
const selectFunc = selectFunctions.get(db.selectId);
const selectFunc = globalVal._briskOrmSelectFunctions!.get(db.selectId);
if (!selectFunc) {
continue;
}
Expand Down Expand Up @@ -177,7 +246,9 @@ export function getSelect<T>(
const argsRes = (isContext ? args.slice(0, args.length - 1) : args).map((item, index) => {
if (sqlArgs?.includes(index)) {
return {
toSqlString: () => ((typeof item === 'object' && typeof item.toSqlString === 'function') ? item.toSqlString(mapping) : item),
toSqlString: () => ((typeof item === 'object' && typeof item.toSqlString === 'function')
? item.toSqlString(mapping, targetDes?.meta?.softDelete)
: item),
};
}
return item;
Expand Down Expand Up @@ -214,15 +285,18 @@ export function getSelect<T>(
};

if (id) {
selectFunctions.set(id, selectFunc);
globalVal._briskOrmSelectFunctions!.set(id, selectFunc);
}

return selectFunc;
}

function transToValue(_value: any) {
// 空和非对象,日期,都直接返回
if (!_value || typeof _value !== 'object' || _value instanceof Date) {
function transToValue(_value: any, defaultVal?: any) {
if (_value === undefined || _value === null) {
return defaultVal;
}
// 非对象,日期,都直接返回
if (typeof _value !== 'object' || _value instanceof Date) {
return _value;
}

Expand All @@ -241,16 +315,16 @@ function transToValue(_value: any) {
}


function transToValues(data: any, propertis: string[]): any[] {
function transToValues(data: any, propertis: string[], propertiesDes?: PropertiesDes[]): any[] {
if (typeof data !== 'object') {
return [];
}

// 数组,则转换成一个二维数组,子数组为对象的值数组
if (Array.isArray(data)) {
return data.map((item) => transToValues(item, propertis)[0]);
return data.map((item) => transToValues(item, propertis, propertiesDes)[0]);
}
return [propertis.map((item) => transToValue(data[item]))];
return [propertis.map((item) => transToValue(data[item], propertiesDes?.find((p) => p.key === item)?.meta?.default))];
}

/**
Expand All @@ -262,10 +336,12 @@ function transToValues(data: any, propertis: string[]): any[] {
export function getInsert<T>(
sql: string,
propertis: string[],
Target?: Class,
): BriskOrmInsertFunction<T> {
const insertFunc = async function(data: T, ctx?: BriskOrmContext) {
try {
const res = await query(sql, [transToValues(data, propertis)], ctx);
const targetDes = runtime.get(Target?.name || '');
const res = await query(sql, [transToValues(data, propertis, targetDes?.properties)], ctx);
return {
success: res ? !res.fieldCount : false,
affectedRows: res?.affectedRows || 0,
Expand All @@ -284,28 +360,33 @@ export function getInsert<T>(
* @param propertis 修改对象的字段列表,需要按set顺序填写
* @param mapping 映射对象
* @param sqlArgs 作为原生SQL插入的参数序号
* @param Target 目标对象
* @returns
*/
export function getUpdate<T>(
sql: string,
propertis: string[],
mapping?: BriskOrmEntityMapping,
sqlArgs?: number[],
Target?: Class,
): BriskOrmUpdateFunction<T> {
const updateFunc = async(data: Partial<T>, ...args: any[]) => {
try {
const ctx = args[args.length - 1];
const isContext = isLike<BriskOrmContext>(ctx);
const targetDes = runtime.get(Target?.name || '');
const argsRes = (isContext ? args.slice(0, args.length - 1) : args).map((item, index) => {
// 加一是因为data作为第一个参数
if (sqlArgs?.includes(index + 1)) {
return {
toSqlString: () => ((typeof item === 'object' && typeof item.toSqlString === 'function') ? item.toSqlString(mapping) : item),
toSqlString: () => ((typeof item === 'object' && typeof item.toSqlString === 'function')
? item.toSqlString(mapping, targetDes?.meta?.softDelete)
: item),
};
}
return item;
});
const values = [...(transToValues(data, propertis)[0]), ...argsRes];
const values = [...(transToValues(data, propertis, targetDes?.properties)[0]), ...argsRes];
const res = await query(sql, values, isLike<BriskOrmContext>(ctx) ? ctx : undefined);
return {
success: res ? !res.fieldCount : false,
Expand All @@ -325,21 +406,27 @@ export function getUpdate<T>(
* @param sql sql语句
* @param mapping 映射对象
* @param sqlArgs 作为原生SQL插入的参数序号
* @param id 删除方法的id
* @returns
*/
export function getDelete(
sql: string,
mapping?: BriskOrmEntityMapping,
sqlArgs?: number[],
Target?: Class,
id?: string,
): BriskOrmDeleteFunction {
const deleteFunc = async(...args: any[]) => {
try {
const ctx = args[args.length - 1];
const isContext = isLike<BriskOrmContext>(ctx);
const targetDes = runtime.get(Target?.name || '');
const argsRes = (isContext ? args.slice(0, args.length - 1) : args).map((item, index) => {
if (sqlArgs?.includes(index)) {
return {
toSqlString: () => ((typeof item === 'object' && typeof item.toSqlString === 'function') ? item.toSqlString(mapping) : item),
toSqlString: () => ((typeof item === 'object' && typeof item.toSqlString === 'function')
? item.toSqlString(mapping, targetDes?.meta?.softDelete)
: item),
};
}
return item;
Expand All @@ -355,5 +442,9 @@ export function getDelete(
}
};

if (id) {
globalVal._briskOrmDeleteFunctions?.set(id, deleteFunc);
}

return deleteFunc;
}
Loading

0 comments on commit 2236765

Please sign in to comment.