@axiosleo/orm-mysql 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env +1 -1
- package/README.md +39 -1
- package/index.d.ts +48 -2
- package/index.js +17 -2
- package/package.json +1 -1
- package/runtimes/test.js +64 -40
- package/src/builder.js +3 -0
- package/src/client.js +49 -1
- package/src/operator.js +19 -13
- package/src/query.js +3 -1
- package/src/transaction.js +111 -0
package/.env
CHANGED
package/README.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# @axiosleo/orm-mysql
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
[](https://npmjs.org/package/@axiosleo/orm-mysql)
|
|
4
5
|
[](https://npmjs.org/package/@axiosleo/orm-mysql)
|
|
5
6
|
[](LICENSE)
|
|
6
|
-
[](https://app.fossa.com/projects/git%2Bgithub.com%2FAxiosLeo%2Fnode-orm-mysql
|
|
7
|
+
[](https://app.fossa.com/projects/git%2Bgithub.com%2FAxiosLeo%2Fnode-orm-mysql?ref=badge_shield)
|
|
7
8
|
|
|
8
9
|
## Installation
|
|
9
10
|
|
|
@@ -150,6 +151,43 @@ Hook.post(async (options, result) => {
|
|
|
150
151
|
}, { table: 'table_name', opt: 'insert' });
|
|
151
152
|
```
|
|
152
153
|
|
|
154
|
+
### Transaction
|
|
155
|
+
|
|
156
|
+
```javascript
|
|
157
|
+
const { TransactionHandler, createPromiseClient } = require("@axiosleo/orm-mysql");
|
|
158
|
+
|
|
159
|
+
const conn = createPromiseClient({
|
|
160
|
+
host: process.env.MYSQL_HOST,
|
|
161
|
+
port: process.env.MYSQL_PORT,
|
|
162
|
+
user: process.env.MYSQL_USER,
|
|
163
|
+
password: process.env.MYSQL_PASS,
|
|
164
|
+
database: process.env.MYSQL_DB,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const transaction = new TransactionHandler(connection);
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
// insert user info
|
|
171
|
+
let row = await transaction.table("users").insert({
|
|
172
|
+
name: "Joe",
|
|
173
|
+
age: 18,
|
|
174
|
+
});
|
|
175
|
+
const lastInsertId = row[0].insertId;
|
|
176
|
+
|
|
177
|
+
// insert student info
|
|
178
|
+
await transaction.table("students").insert({
|
|
179
|
+
user_id: lastInsertId,
|
|
180
|
+
});
|
|
181
|
+
await transaction.commit();
|
|
182
|
+
} catch (e) {
|
|
183
|
+
await transaction.rollback();
|
|
184
|
+
throw e;
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
153
188
|
## License
|
|
154
189
|
|
|
155
190
|
This project is open-sourced software licensed under the [MIT](LICENSE).
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
[](https://app.fossa.com/projects/git%2Bgithub.com%2FAxiosLeo%2Fnode-orm-mysql?ref=badge_large)
|
package/index.d.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
+
Pool,
|
|
2
3
|
OkPacket,
|
|
3
4
|
Connection,
|
|
5
|
+
PoolOptions,
|
|
4
6
|
QueryOptions,
|
|
5
7
|
RowDataPacket,
|
|
6
8
|
ConnectionOptions
|
|
7
9
|
} from 'mysql2';
|
|
8
10
|
|
|
11
|
+
import {
|
|
12
|
+
Connection as PromiseConnection,
|
|
13
|
+
} from 'mysql2/promise';
|
|
14
|
+
|
|
9
15
|
export type Clients = {
|
|
10
16
|
[key: string]: Connection
|
|
11
17
|
}
|
|
@@ -54,6 +60,8 @@ export interface QueryOperatorOptions {
|
|
|
54
60
|
groupField: string[];
|
|
55
61
|
joins: JoinOption[];
|
|
56
62
|
having: WhereOptions[];
|
|
63
|
+
suffix?: string | null;
|
|
64
|
+
transaction: boolean;
|
|
57
65
|
}
|
|
58
66
|
|
|
59
67
|
export declare class Query {
|
|
@@ -112,7 +120,12 @@ export declare class QueryOperator extends Query {
|
|
|
112
120
|
|
|
113
121
|
count(): Promise<number>;
|
|
114
122
|
|
|
115
|
-
|
|
123
|
+
/**
|
|
124
|
+
* delete data
|
|
125
|
+
* @param id
|
|
126
|
+
* @param index_field_name default is 'id'
|
|
127
|
+
*/
|
|
128
|
+
delete(id?: number, index_field_name?: string): Promise<OkPacket>;
|
|
116
129
|
}
|
|
117
130
|
|
|
118
131
|
export declare class QueryHandler {
|
|
@@ -127,10 +140,43 @@ export declare class QueryHandler {
|
|
|
127
140
|
upsert(tableName: string, data: any, condition: Record<string, ConditionValueType>): Promise<OkPacket>;
|
|
128
141
|
}
|
|
129
142
|
|
|
143
|
+
export declare class TransactionOperator extends QueryOperator {
|
|
144
|
+
append(suffix: string): this;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export declare class TransactionHandler {
|
|
148
|
+
constructor(conn: PromiseConnection, options?: {
|
|
149
|
+
level: 'READ UNCOMMITTED' | 'RU'
|
|
150
|
+
| 'READ COMMITTED' | 'RC'
|
|
151
|
+
| 'REPEATABLE READ' | 'RR'
|
|
152
|
+
| 'SERIALIZABLE' | 'S'
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
query(options: QueryOptions): Promise<any>;
|
|
156
|
+
|
|
157
|
+
execute(sql: string, values: any[]): Promise<any>;
|
|
158
|
+
|
|
159
|
+
lastInsertId(alias?: string): Promise<number>;
|
|
160
|
+
|
|
161
|
+
table(table: string, alias?: string | null): TransactionOperator;
|
|
162
|
+
|
|
163
|
+
begin(): Promise<void>;
|
|
164
|
+
|
|
165
|
+
commit(): Promise<void>;
|
|
166
|
+
|
|
167
|
+
rollback(): Promise<void>;
|
|
168
|
+
|
|
169
|
+
upsert(tableName: string, data: any, condition: Record<string, ConditionValueType>): Promise<OkPacket>;
|
|
170
|
+
}
|
|
171
|
+
|
|
130
172
|
export function createClient(options: ConnectionOptions, name?: string | null | undefined): Connection;
|
|
131
173
|
|
|
132
174
|
export function getClient(name: string): Connection;
|
|
133
175
|
|
|
176
|
+
export function createPool(options: PoolOptions, name?: string | null | undefined): Pool;
|
|
177
|
+
|
|
178
|
+
export function createPromiseClient(options: ConnectionOptions, name?: string | null | undefined): PromiseConnection;
|
|
179
|
+
|
|
134
180
|
export declare class Hook {
|
|
135
181
|
static pre: (
|
|
136
182
|
callback: (options: QueryOperatorOptions) => void,
|
|
@@ -141,4 +187,4 @@ export declare class Hook {
|
|
|
141
187
|
callback: (options: QueryOperatorOptions, result: QueryResult | Error) => void,
|
|
142
188
|
option: { table?: string, opt?: OperatorType }
|
|
143
189
|
) => string;
|
|
144
|
-
}
|
|
190
|
+
}
|
package/index.js
CHANGED
|
@@ -6,7 +6,17 @@ const {
|
|
|
6
6
|
Query
|
|
7
7
|
} = require('./src/operator');
|
|
8
8
|
|
|
9
|
-
const {
|
|
9
|
+
const {
|
|
10
|
+
TransactionOperator,
|
|
11
|
+
TransactionHandler
|
|
12
|
+
} = require('./src/transaction');
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
getClient,
|
|
16
|
+
createPool,
|
|
17
|
+
createClient,
|
|
18
|
+
createPromiseClient
|
|
19
|
+
} = require('./src/client');
|
|
10
20
|
|
|
11
21
|
const { Hook } = require('./src/hook');
|
|
12
22
|
|
|
@@ -17,6 +27,11 @@ module.exports = {
|
|
|
17
27
|
QueryHandler,
|
|
18
28
|
QueryOperator,
|
|
19
29
|
|
|
30
|
+
TransactionOperator,
|
|
31
|
+
TransactionHandler,
|
|
32
|
+
|
|
20
33
|
getClient,
|
|
21
|
-
|
|
34
|
+
createPool,
|
|
35
|
+
createClient,
|
|
36
|
+
createPromiseClient
|
|
22
37
|
};
|
package/package.json
CHANGED
package/runtimes/test.js
CHANGED
|
@@ -1,49 +1,73 @@
|
|
|
1
|
+
/* eslint-disable no-unused-vars */
|
|
1
2
|
/* eslint-disable no-console */
|
|
2
3
|
'use strict';
|
|
3
4
|
|
|
5
|
+
const path = require('path');
|
|
4
6
|
const dotenv = require('dotenv');
|
|
5
|
-
dotenv.config(
|
|
7
|
+
dotenv.config({
|
|
8
|
+
path: path.join(__dirname, '../.env')
|
|
9
|
+
});
|
|
6
10
|
const { debug } = require('@axiosleo/cli-tool');
|
|
7
11
|
|
|
8
|
-
const mysql = require('mysql2');
|
|
9
|
-
const {
|
|
10
|
-
QueryHandler,
|
|
11
|
-
// Query
|
|
12
|
-
} = require('../src/operator');
|
|
13
|
-
const { Hook } = require('../index');
|
|
14
|
-
|
|
15
|
-
const conn = mysql.createConnection({
|
|
16
|
-
host: process.env.MYSQL_HOST,
|
|
17
|
-
port: process.env.MYSQL_PORT,
|
|
18
|
-
user: process.env.MYSQL_USER,
|
|
19
|
-
password: process.env.MYSQL_PASS,
|
|
20
|
-
database: process.env.MYSQL_DB,
|
|
21
|
-
});
|
|
22
|
-
const hanlder = new QueryHandler(conn);
|
|
12
|
+
const mysql = require('mysql2/promise');
|
|
23
13
|
|
|
24
|
-
|
|
25
|
-
debug.log('options', options);
|
|
26
|
-
}, {
|
|
27
|
-
table: 'test',
|
|
28
|
-
opt: 'insert'
|
|
29
|
-
});
|
|
30
|
-
Hook.postInsert(async (options, result) => {
|
|
31
|
-
throw new Error('some error');
|
|
32
|
-
}, { table: 'test', opt: 'insert' });
|
|
14
|
+
const { TransactionHandler } = require('../src/transaction');
|
|
33
15
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
16
|
+
async function main() {
|
|
17
|
+
const items = ['RI0002', 'CB0004'];
|
|
18
|
+
const config = {
|
|
19
|
+
user: process.env.MYSQL_USER,
|
|
20
|
+
password: process.env.MYSQL_PASS,
|
|
21
|
+
host: process.env.MYSQL_HOST,
|
|
22
|
+
port: process.env.MYSQL_PORT,
|
|
23
|
+
database: process.env.MYSQL_DB,
|
|
24
|
+
};
|
|
25
|
+
const connection = await mysql.createConnection(config);
|
|
26
|
+
const transaction = new TransactionHandler(connection);
|
|
27
|
+
await transaction.begin();
|
|
28
|
+
console.log('Finished setting the isolation level to read committed');
|
|
29
|
+
try {
|
|
30
|
+
await transaction.table('product').attr('id', 'name').where('sku', items, 'IN').append('FOR UPDATE').select();
|
|
31
|
+
console.log(`Locked rows for skus ${items.join()}`);
|
|
32
|
+
const [itemsToOrder] = await transaction.table('product').attr('name', 'quantity', 'price').where('sku', items, 'IN').orderBy('id').select();
|
|
33
|
+
console.log('Selected quantities for items');
|
|
34
|
+
let orderTotal = 0;
|
|
35
|
+
let orderItems = [];
|
|
36
|
+
for (let itemToOrder of itemsToOrder) {
|
|
37
|
+
if (itemToOrder.quantity < 1) {
|
|
38
|
+
throw new Error(`One of the items is out of stock ${itemToOrder.name}`);
|
|
39
|
+
}
|
|
40
|
+
console.log(`Quantity for ${itemToOrder.name} is ${itemToOrder.quantity}`);
|
|
41
|
+
orderTotal += itemToOrder.price;
|
|
42
|
+
orderItems.push(itemToOrder.name);
|
|
43
|
+
}
|
|
44
|
+
const res = await transaction.table('sales_order').insert({
|
|
45
|
+
items: orderItems.join(),
|
|
46
|
+
total: orderTotal,
|
|
47
|
+
});
|
|
48
|
+
// const lastInsertId = res[0].insertId;
|
|
49
|
+
debug.log('result', res);
|
|
50
|
+
await debug.pause('pause', {
|
|
51
|
+
items: orderItems.join(),
|
|
52
|
+
total: orderTotal,
|
|
53
|
+
});
|
|
54
|
+
console.log('Order created');
|
|
55
|
+
await transaction.execute(
|
|
56
|
+
'UPDATE product SET quantity=quantity - 1 WHERE sku IN (?, ?)',
|
|
57
|
+
items
|
|
58
|
+
);
|
|
59
|
+
console.log(`Deducted quantities by 1 for ${items.join()}`);
|
|
60
|
+
await transaction.commit();
|
|
61
|
+
const lastInsertId = await transaction.lastInsertId('order_id');
|
|
62
|
+
debug.log(`order created with id ${lastInsertId}`);
|
|
63
|
+
return `order created with id ${lastInsertId}`;
|
|
64
|
+
} catch (err) {
|
|
65
|
+
console.error(`Error occurred while creating order: ${err.message}`, err);
|
|
66
|
+
transaction.rollback();
|
|
67
|
+
console.info('Rollback successful');
|
|
68
|
+
debug.log('error creating order');
|
|
69
|
+
return 'error creating order';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
48
72
|
|
|
49
|
-
|
|
73
|
+
main();
|
package/src/builder.js
CHANGED
package/src/client.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const mysql = require('mysql2');
|
|
4
|
+
const mysqlPromise = require('mysql2/promise');
|
|
4
5
|
const { validate } = require('./utils');
|
|
5
6
|
|
|
6
7
|
const clients = {};
|
|
@@ -28,6 +29,51 @@ const createClient = (options, name = null) => {
|
|
|
28
29
|
return clients[key];
|
|
29
30
|
};
|
|
30
31
|
|
|
32
|
+
/**
|
|
33
|
+
* @param {mysql.ConnectionOptions} options
|
|
34
|
+
* @param {string|null} name
|
|
35
|
+
* @returns {mysqlPromise.Connection}
|
|
36
|
+
*/
|
|
37
|
+
const createPromiseClient = async (options, name = null) => {
|
|
38
|
+
validate(options, {
|
|
39
|
+
host: 'required|string',
|
|
40
|
+
user: 'required|string',
|
|
41
|
+
password: 'required|string',
|
|
42
|
+
port: 'required|integer',
|
|
43
|
+
database: 'required|string',
|
|
44
|
+
});
|
|
45
|
+
const key = name ? name :
|
|
46
|
+
`${options.host}:${options.port}:${options.user}:${options.password}:${options.database}`;
|
|
47
|
+
if (clients[key]) {
|
|
48
|
+
return clients[key];
|
|
49
|
+
}
|
|
50
|
+
clients[key] = await mysqlPromise.createConnection(options);
|
|
51
|
+
return clients[key];
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* create pool
|
|
56
|
+
* @param {mysql.PoolOptions} options
|
|
57
|
+
* @returns {mysql.Pool}
|
|
58
|
+
*/
|
|
59
|
+
const createPool = (options, name = null) => {
|
|
60
|
+
validate(options, {
|
|
61
|
+
host: 'required|string',
|
|
62
|
+
user: 'required|string',
|
|
63
|
+
password: 'required|string',
|
|
64
|
+
port: 'required|integer',
|
|
65
|
+
database: 'required|string',
|
|
66
|
+
});
|
|
67
|
+
const key = name ? name :
|
|
68
|
+
`${options.host}:${options.port}:${options.user}:${options.password}:${options.database}`;
|
|
69
|
+
if (clients[key]) {
|
|
70
|
+
return clients[key];
|
|
71
|
+
}
|
|
72
|
+
const pool = mysql.createPool(options);
|
|
73
|
+
clients[key] = pool;
|
|
74
|
+
return pool;
|
|
75
|
+
};
|
|
76
|
+
|
|
31
77
|
/**
|
|
32
78
|
* get client
|
|
33
79
|
* @param {*} name
|
|
@@ -45,5 +91,7 @@ const getClient = (name) => {
|
|
|
45
91
|
|
|
46
92
|
module.exports = {
|
|
47
93
|
getClient,
|
|
48
|
-
|
|
94
|
+
createPool,
|
|
95
|
+
createClient,
|
|
96
|
+
createPromiseClient
|
|
49
97
|
};
|
package/src/operator.js
CHANGED
|
@@ -4,15 +4,21 @@ const { Builder } = require('./builder');
|
|
|
4
4
|
const Query = require('./query');
|
|
5
5
|
const { handleEvent } = require('./hook');
|
|
6
6
|
|
|
7
|
-
const query = async (conn, options) => {
|
|
7
|
+
const query = async (conn, options, transaction) => {
|
|
8
8
|
return new Promise((resolve, reject) => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
if (transaction) {
|
|
10
|
+
conn.execute(options)
|
|
11
|
+
.then((res) => resolve(res))
|
|
12
|
+
.catch((err) => reject(err));
|
|
13
|
+
} else {
|
|
14
|
+
conn.query(options, (err, result) => {
|
|
15
|
+
if (err) {
|
|
16
|
+
reject(err);
|
|
17
|
+
} else {
|
|
18
|
+
resolve(result);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
16
22
|
});
|
|
17
23
|
};
|
|
18
24
|
|
|
@@ -45,17 +51,17 @@ class QueryOperator extends Query {
|
|
|
45
51
|
try {
|
|
46
52
|
switch (this.options.operator) {
|
|
47
53
|
case 'find': {
|
|
48
|
-
const tmp = await query(this.conn, options);
|
|
54
|
+
const tmp = await query(this.conn, options, this.options.transaction);
|
|
49
55
|
res = tmp[0];
|
|
50
56
|
break;
|
|
51
57
|
}
|
|
52
58
|
case 'count': {
|
|
53
|
-
const [tmp] = await query(this.conn, options);
|
|
59
|
+
const [tmp] = await query(this.conn, options, this.options.transaction);
|
|
54
60
|
res = tmp.count;
|
|
55
61
|
break;
|
|
56
62
|
}
|
|
57
63
|
default:
|
|
58
|
-
res = await query(this.conn, options);
|
|
64
|
+
res = await query(this.conn, options, this.options.transaction);
|
|
59
65
|
}
|
|
60
66
|
handleEvent('post', from, this.options.operator, this.options, res);
|
|
61
67
|
} catch (err) {
|
|
@@ -96,9 +102,9 @@ class QueryOperator extends Query {
|
|
|
96
102
|
return await this.exec();
|
|
97
103
|
}
|
|
98
104
|
|
|
99
|
-
async delete(id) {
|
|
105
|
+
async delete(id, index_field_name = 'id') {
|
|
100
106
|
if (id) {
|
|
101
|
-
this.where(
|
|
107
|
+
this.where(index_field_name, id);
|
|
102
108
|
}
|
|
103
109
|
this.options.operator = 'delete';
|
|
104
110
|
return await this.exec();
|
package/src/query.js
CHANGED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line no-unused-vars
|
|
4
|
+
const mysql = require('mysql2/promise');
|
|
5
|
+
const { QueryOperator } = require('./operator');
|
|
6
|
+
|
|
7
|
+
const levels = {
|
|
8
|
+
RU: 'READ UNCOMMITTED',
|
|
9
|
+
RC: 'READ COMMITTED',
|
|
10
|
+
RR: 'REPEATABLE READ',
|
|
11
|
+
S: 'SERIALIZABLE'
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
class TransactionOperator extends QueryOperator {
|
|
15
|
+
/**
|
|
16
|
+
* @param {*} conn
|
|
17
|
+
*/
|
|
18
|
+
constructor(conn) {
|
|
19
|
+
super(conn);
|
|
20
|
+
this.options.transaction = true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @example LOCK IN SHARE MODE
|
|
25
|
+
* @example FOR UPDATE
|
|
26
|
+
*/
|
|
27
|
+
append(suffix) {
|
|
28
|
+
this.options.suffix = suffix || null;
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
class TransactionHandler {
|
|
34
|
+
/**
|
|
35
|
+
* @param {mysql.Connection} conn
|
|
36
|
+
* @param {mysql.ConnectionOptions} options
|
|
37
|
+
*/
|
|
38
|
+
constructor(conn, options = {}) {
|
|
39
|
+
this.isbegin = false;
|
|
40
|
+
this.conn = conn;
|
|
41
|
+
this.level = options.level || 'SERIALIZABLE';
|
|
42
|
+
if (levels[this.level]) {
|
|
43
|
+
this.level = levels[this.level];
|
|
44
|
+
}
|
|
45
|
+
if (!Object.values(levels).includes(this.level)) {
|
|
46
|
+
throw new Error('Invalid transaction level: ' + this.level);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async query(options) {
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
this.conn.query(options, (err, result) => {
|
|
53
|
+
if (err) {
|
|
54
|
+
reject(err);
|
|
55
|
+
} else {
|
|
56
|
+
resolve(result);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async execute(sql, values = []) {
|
|
63
|
+
return this.conn.execute(sql, values);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async lastInsertId(alias = 'insert_id') {
|
|
67
|
+
let sql = `SELECT LAST_INSERT_ID() as ${alias}`;
|
|
68
|
+
const [row] = await this.execute(sql);
|
|
69
|
+
return row && row[0] ? row[0][alias] : 0;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async begin() {
|
|
73
|
+
this.isbegin = true;
|
|
74
|
+
await this.execute(`SET TRANSACTION ISOLATION LEVEL ${this.level}`);
|
|
75
|
+
await this.conn.beginTransaction();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
table(table, alias = null) {
|
|
79
|
+
if (!this.isbegin) {
|
|
80
|
+
throw new Error('Transaction is not begin');
|
|
81
|
+
}
|
|
82
|
+
return (new TransactionOperator(this.conn)).table(table, alias);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async upsert(tableName, data, condition = {}) {
|
|
86
|
+
const count = await this.table(tableName).whereObject(condition).count();
|
|
87
|
+
if (count) {
|
|
88
|
+
return await this.table(tableName).whereObject(condition).update(data);
|
|
89
|
+
}
|
|
90
|
+
return await this.table(tableName).insert(data);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async commit() {
|
|
94
|
+
if (!this.isbegin) {
|
|
95
|
+
throw new Error('Transaction is not begin');
|
|
96
|
+
}
|
|
97
|
+
await this.conn.commit();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async rollback() {
|
|
101
|
+
if (!this.isbegin) {
|
|
102
|
+
throw new Error('Transaction is not begin');
|
|
103
|
+
}
|
|
104
|
+
await this.conn.rollback();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
module.exports = {
|
|
109
|
+
TransactionOperator,
|
|
110
|
+
TransactionHandler
|
|
111
|
+
};
|