3.2.2-publish

This commit is contained in:
Xu Chang 2024-03-29 18:50:51 +08:00
parent 6378af8cf6
commit b347bc7915
5 changed files with 33 additions and 33 deletions

View File

@ -20,6 +20,7 @@ class MySqlConnector {
return this.pool.end(); return this.pool.end();
} }
async startTransaction(option) { async startTransaction(option) {
// 防止用户配置connection可复用
const startInner = async () => { const startInner = async () => {
const connection = await this.pool.getConnection(); const connection = await this.pool.getConnection();
// 分配出来的connection不能被别的事务占据 // 分配出来的connection不能被别的事务占据
@ -32,7 +33,7 @@ class MySqlConnector {
} }
await connection.beginTransaction(); await connection.beginTransaction();
const id = (0, uuid_1.v4)(); const id = (0, uuid_1.v4)();
console.log('start_txn', id, connection.threadId); // console.log('start_txn', id, connection.threadId);
this.txnDict[id] = connection; this.txnDict[id] = connection;
if (option?.isolationLevel) { if (option?.isolationLevel) {
await connection.query(`SET TRANSACTION ISOLATION LEVEL ${option.isolationLevel};`); await connection.query(`SET TRANSACTION ISOLATION LEVEL ${option.isolationLevel};`);
@ -58,18 +59,16 @@ class MySqlConnector {
} }
async commitTransaction(txn) { async commitTransaction(txn) {
const connection = this.txnDict[txn]; const connection = this.txnDict[txn];
if(!connection) { (0, assert_1.default)(connection);
console.log('qiguai!');
}
delete this.txnDict[txn]; delete this.txnDict[txn];
console.log('commit_txn', txn, connection.threadId); // console.log('commit_txn', txn, connection.threadId);
await connection.commit(); await connection.commit();
connection.release(); connection.release();
} }
async rollbackTransaction(txn) { async rollbackTransaction(txn) {
const connection = this.txnDict[txn]; const connection = this.txnDict[txn];
(0, assert_1.default)(connection); (0, assert_1.default)(connection);
console.log('rollback_txn', txn, connection.threadId); // console.log('rollback_txn', txn, connection.threadId);
await connection.rollback(); await connection.rollback();
delete this.txnDict[txn]; delete this.txnDict[txn];
connection.release(); connection.release();

22
lib/MySQL/store.d.ts vendored
View File

@ -4,28 +4,28 @@ import { CascadeStore } from 'oak-domain/lib/store/CascadeStore';
import { MySQLConfiguration } from './types/Configuration'; import { MySQLConfiguration } from './types/Configuration';
import { MySqlConnector } from './connector'; import { MySqlConnector } from './connector';
import { MySqlTranslator, MySqlSelectOption, MysqlOperateOption } from './translator'; import { MySqlTranslator, MySqlSelectOption, MysqlOperateOption } from './translator';
import { BackendRuntimeContext, AsyncRowStore } from 'oak-domain/lib/store/AsyncRowStore'; import { AsyncContext, AsyncRowStore } from 'oak-domain/lib/store/AsyncRowStore';
import { FrontendRuntimeContext } from 'oak-domain/lib/store/SyncRowStore'; import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
import { CreateEntityOption } from '../types/Translator'; import { CreateEntityOption } from '../types/Translator';
export declare class MysqlStore<ED extends EntityDict & BaseEntityDict, Cxt extends BackendRuntimeContext<ED>> extends CascadeStore<ED> implements AsyncRowStore<ED, Cxt> { export declare class MysqlStore<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> extends CascadeStore<ED> implements AsyncRowStore<ED, Cxt> {
protected countAbjointRow<T extends keyof ED, OP extends SelectOption, Cxt extends FrontendRuntimeContext<ED>>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: Cxt, option: OP): number; protected countAbjointRow<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED>>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: Cxt, option: OP): number;
protected aggregateAbjointRowSync<T extends keyof ED, OP extends SelectOption, Cxt extends FrontendRuntimeContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): AggregationResult<ED[T]['Schema']>; protected aggregateAbjointRowSync<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): AggregationResult<ED[T]['Schema']>;
protected selectAbjointRow<T extends keyof ED, OP extends SelectOption>(entity: T, selection: ED[T]['Selection'], context: FrontendRuntimeContext<ED>, option: OP): Partial<ED[T]['Schema']>[]; protected selectAbjointRow<T extends keyof ED, OP extends SelectOption>(entity: T, selection: ED[T]['Selection'], context: SyncContext<ED>, option: OP): Partial<ED[T]['Schema']>[];
protected updateAbjointRow<T extends keyof ED, OP extends OperateOption>(entity: T, operation: ED[T]['Operation'], context: FrontendRuntimeContext<ED>, option: OP): number; protected updateAbjointRow<T extends keyof ED, OP extends OperateOption>(entity: T, operation: ED[T]['Operation'], context: SyncContext<ED>, option: OP): number;
exec(script: string, txnId?: string): Promise<any>; exec(script: string, txnId?: string): Promise<any>;
connector: MySqlConnector; connector: MySqlConnector;
translator: MySqlTranslator<ED>; translator: MySqlTranslator<ED>;
constructor(storageSchema: StorageSchema<ED>, configuration: MySQLConfiguration); constructor(storageSchema: StorageSchema<ED>, configuration: MySQLConfiguration);
protected aggregateAbjointRowAsync<T extends keyof ED, OP extends SelectOption, Cxt extends BackendRuntimeContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): Promise<AggregationResult<ED[T]['Schema']>>; protected aggregateAbjointRowAsync<T extends keyof ED, OP extends SelectOption, Cxt extends AsyncContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): Promise<AggregationResult<ED[T]['Schema']>>;
aggregate<T extends keyof ED, OP extends SelectOption>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): Promise<AggregationResult<ED[T]['Schema']>>; aggregate<T extends keyof ED, OP extends SelectOption>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): Promise<AggregationResult<ED[T]['Schema']>>;
protected supportManyToOneJoin(): boolean; protected supportManyToOneJoin(): boolean;
protected supportMultipleCreate(): boolean; protected supportMultipleCreate(): boolean;
private formResult; private formResult;
protected selectAbjointRowAsync<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: BackendRuntimeContext<ED>, option?: MySqlSelectOption): Promise<Partial<ED[T]['Schema']>[]>; protected selectAbjointRowAsync<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: AsyncContext<ED>, option?: MySqlSelectOption): Promise<Partial<ED[T]['Schema']>[]>;
protected updateAbjointRowAsync<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: BackendRuntimeContext<ED>, option?: MysqlOperateOption): Promise<number>; protected updateAbjointRowAsync<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: AsyncContext<ED>, option?: MysqlOperateOption): Promise<number>;
operate<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: OperateOption): Promise<OperationResult<ED>>; operate<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: OperateOption): Promise<OperationResult<ED>>;
select<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: SelectOption): Promise<Partial<ED[T]['Schema']>[]>; select<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: SelectOption): Promise<Partial<ED[T]['Schema']>[]>;
protected countAbjointRowAsync<T extends keyof ED>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: BackendRuntimeContext<ED>, option: SelectOption): Promise<number>; protected countAbjointRowAsync<T extends keyof ED>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: AsyncContext<ED>, option: SelectOption): Promise<number>;
count<T extends keyof ED>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: Cxt, option: SelectOption): Promise<number>; count<T extends keyof ED>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: Cxt, option: SelectOption): Promise<number>;
begin(option?: TxnOption): Promise<string>; begin(option?: TxnOption): Promise<string>;
commit(txnId: string): Promise<void>; commit(txnId: string): Promise<void>;

View File

@ -18,7 +18,7 @@
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mysql": "^2.18.1", "mysql": "^2.18.1",
"mysql2": "^2.3.3", "mysql2": "^2.3.3",
"oak-domain": "file:../oak-domain", "oak-domain": "^4.5.0",
"uuid": "^8.3.2" "uuid": "^8.3.2"
}, },
"license": "ISC", "license": "ISC",
@ -31,7 +31,7 @@
"@types/uuid": "^8.3.4", "@types/uuid": "^8.3.4",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"mocha": "^10.2.0", "mocha": "^10.2.0",
"oak-general-business": "file:../oak-general-business", "oak-general-business": "^4.4.0",
"ts-node": "^10.9.1", "ts-node": "^10.9.1",
"tslib": "^2.4.0", "tslib": "^2.4.0",
"typescript": "^5.2.2" "typescript": "^5.2.2"

View File

@ -24,6 +24,7 @@ export class MySqlConnector {
} }
async startTransaction(option?: TxnOption): Promise<string> { async startTransaction(option?: TxnOption): Promise<string> {
// 防止用户配置connection可复用
const startInner = async (): Promise<string> => { const startInner = async (): Promise<string> => {
const connection = await this.pool.getConnection(); const connection = await this.pool.getConnection();
@ -40,7 +41,7 @@ export class MySqlConnector {
await connection.beginTransaction(); await connection.beginTransaction();
const id = v4(); const id = v4();
console.log('start_txn', id, connection.threadId); // console.log('start_txn', id, connection.threadId);
this.txnDict[id] = connection; this.txnDict[id] = connection;
if (option?.isolationLevel) { if (option?.isolationLevel) {
await connection.query(`SET TRANSACTION ISOLATION LEVEL ${option.isolationLevel};`); await connection.query(`SET TRANSACTION ISOLATION LEVEL ${option.isolationLevel};`);
@ -71,7 +72,7 @@ export class MySqlConnector {
const connection = this.txnDict[txn]; const connection = this.txnDict[txn];
assert(connection); assert(connection);
delete this.txnDict[txn]; delete this.txnDict[txn];
console.log('commit_txn', txn, connection.threadId); // console.log('commit_txn', txn, connection.threadId);
await connection.commit(); await connection.commit();
connection.release(); connection.release();
} }
@ -79,7 +80,7 @@ export class MySqlConnector {
async rollbackTransaction(txn: string): Promise<void> { async rollbackTransaction(txn: string): Promise<void> {
const connection = this.txnDict[txn]; const connection = this.txnDict[txn];
assert(connection); assert(connection);
console.log('rollback_txn', txn, connection.threadId); // console.log('rollback_txn', txn, connection.threadId);
await connection.rollback(); await connection.rollback();
delete this.txnDict[txn]; delete this.txnDict[txn];
connection.release(); connection.release();

View File

@ -7,8 +7,8 @@ import { MySqlTranslator, MySqlSelectOption, MysqlOperateOption } from './transl
import { assign, set } from 'lodash'; import { assign, set } from 'lodash';
import assert from 'assert'; import assert from 'assert';
import { judgeRelation } from 'oak-domain/lib/store/relation'; import { judgeRelation } from 'oak-domain/lib/store/relation';
import { BackendRuntimeContext, AsyncRowStore } from 'oak-domain/lib/store/AsyncRowStore'; import { AsyncContext, AsyncRowStore } from 'oak-domain/lib/store/AsyncRowStore';
import { FrontendRuntimeContext } from 'oak-domain/lib/store/SyncRowStore'; import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
import { CreateEntityOption } from '../types/Translator'; import { CreateEntityOption } from '../types/Translator';
@ -28,17 +28,17 @@ function convertGeoTextToObject(geoText: string): object {
} }
} }
export class MysqlStore<ED extends EntityDict & BaseEntityDict, Cxt extends BackendRuntimeContext<ED>> extends CascadeStore<ED> implements AsyncRowStore<ED, Cxt>{ export class MysqlStore<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> extends CascadeStore<ED> implements AsyncRowStore<ED, Cxt>{
protected countAbjointRow<T extends keyof ED, OP extends SelectOption, Cxt extends FrontendRuntimeContext<ED>>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: Cxt, option: OP): number { protected countAbjointRow<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED>>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: Cxt, option: OP): number {
throw new Error('MySQL store不支持同步取数据不应该跑到这儿'); throw new Error('MySQL store不支持同步取数据不应该跑到这儿');
} }
protected aggregateAbjointRowSync<T extends keyof ED, OP extends SelectOption, Cxt extends FrontendRuntimeContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): AggregationResult<ED[T]['Schema']> { protected aggregateAbjointRowSync<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): AggregationResult<ED[T]['Schema']> {
throw new Error('MySQL store不支持同步取数据不应该跑到这儿'); throw new Error('MySQL store不支持同步取数据不应该跑到这儿');
} }
protected selectAbjointRow<T extends keyof ED, OP extends SelectOption>(entity: T, selection: ED[T]['Selection'], context: FrontendRuntimeContext<ED>, option: OP): Partial<ED[T]['Schema']>[] { protected selectAbjointRow<T extends keyof ED, OP extends SelectOption>(entity: T, selection: ED[T]['Selection'], context: SyncContext<ED>, option: OP): Partial<ED[T]['Schema']>[] {
throw new Error('MySQL store不支持同步取数据不应该跑到这儿'); throw new Error('MySQL store不支持同步取数据不应该跑到这儿');
} }
protected updateAbjointRow<T extends keyof ED, OP extends OperateOption>(entity: T, operation: ED[T]['Operation'], context: FrontendRuntimeContext<ED>, option: OP): number { protected updateAbjointRow<T extends keyof ED, OP extends OperateOption>(entity: T, operation: ED[T]['Operation'], context: SyncContext<ED>, option: OP): number {
throw new Error('MySQL store不支持同步更新数据不应该跑到这儿'); throw new Error('MySQL store不支持同步更新数据不应该跑到这儿');
} }
exec(script: string, txnId?: string) { exec(script: string, txnId?: string) {
@ -51,7 +51,7 @@ export class MysqlStore<ED extends EntityDict & BaseEntityDict, Cxt extends Back
this.connector = new MySqlConnector(configuration); this.connector = new MySqlConnector(configuration);
this.translator = new MySqlTranslator(storageSchema); this.translator = new MySqlTranslator(storageSchema);
} }
protected async aggregateAbjointRowAsync<T extends keyof ED, OP extends SelectOption, Cxt extends BackendRuntimeContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): Promise<AggregationResult<ED[T]['Schema']>> { protected async aggregateAbjointRowAsync<T extends keyof ED, OP extends SelectOption, Cxt extends AsyncContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): Promise<AggregationResult<ED[T]['Schema']>> {
const sql = this.translator.translateAggregate(entity, aggregation, option); const sql = this.translator.translateAggregate(entity, aggregation, option);
const result = await this.connector.exec(sql, context.getCurrentTxnId()); const result = await this.connector.exec(sql, context.getCurrentTxnId());
return this.formResult(entity, result[0]); return this.formResult(entity, result[0]);
@ -247,7 +247,7 @@ export class MysqlStore<ED extends EntityDict & BaseEntityDict, Cxt extends Back
protected async selectAbjointRowAsync<T extends keyof ED>( protected async selectAbjointRowAsync<T extends keyof ED>(
entity: T, entity: T,
selection: ED[T]['Selection'], selection: ED[T]['Selection'],
context: BackendRuntimeContext<ED>, context: AsyncContext<ED>,
option?: MySqlSelectOption option?: MySqlSelectOption
): Promise<Partial<ED[T]['Schema']>[]> { ): Promise<Partial<ED[T]['Schema']>[]> {
const sql = this.translator.translateSelect(entity, selection, option); const sql = this.translator.translateSelect(entity, selection, option);
@ -258,7 +258,7 @@ export class MysqlStore<ED extends EntityDict & BaseEntityDict, Cxt extends Back
protected async updateAbjointRowAsync<T extends keyof ED>( protected async updateAbjointRowAsync<T extends keyof ED>(
entity: T, entity: T,
operation: ED[T]['Operation'], operation: ED[T]['Operation'],
context: BackendRuntimeContext<ED>, context: AsyncContext<ED>,
option?: MysqlOperateOption option?: MysqlOperateOption
): Promise<number> { ): Promise<number> {
const { translator, connector } = this; const { translator, connector } = this;
@ -296,7 +296,7 @@ export class MysqlStore<ED extends EntityDict & BaseEntityDict, Cxt extends Back
const result = await super.selectAsync(entity, selection, context, option); const result = await super.selectAsync(entity, selection, context, option);
return result; return result;
} }
protected async countAbjointRowAsync<T extends keyof ED>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: BackendRuntimeContext<ED>, option: SelectOption): Promise<number> { protected async countAbjointRowAsync<T extends keyof ED>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: AsyncContext<ED>, option: SelectOption): Promise<number> {
const sql = this.translator.translateCount(entity, selection, option); const sql = this.translator.translateCount(entity, selection, option);
const result = await this.connector.exec(sql, context.getCurrentTxnId()); const result = await this.connector.exec(sql, context.getCurrentTxnId());