@axiosleo/orm-mysql 0.14.0 → 0.14.2

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/bin/orm-mysql.js CHANGED
@@ -9,7 +9,7 @@ const app = new App({
9
9
  name: 'MySQL ORM CLI',
10
10
  desc: 'migrate, model, seed, etc.',
11
11
  bin: 'orm-mysql',
12
- version: '0.14.0',
12
+ version: '0.14.2',
13
13
  commands_dir: path.join(__dirname, '../commands'),
14
14
  });
15
15
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiosleo/orm-mysql",
3
- "version": "0.14.0",
3
+ "version": "0.14.2",
4
4
  "description": "MySQL ORM tool",
5
5
  "keywords": [
6
6
  "mysql",
package/src/builder.js CHANGED
@@ -749,7 +749,7 @@ class ManageSQLBuilder extends Builder {
749
749
  let str = `\`${options.name}\` ${type}`;
750
750
  if (typeof options.length !== 'undefined') {
751
751
  if (type === 'DECIMAL') {
752
- str += `(${options.precision || 10}, ${options.length || 6})`;
752
+ str += `(${options.precision || 10}, ${options.scale || options.length || 6})`;
753
753
  } else {
754
754
  str += `(${options.length})`;
755
755
  }
@@ -760,7 +760,7 @@ class ManageSQLBuilder extends Builder {
760
760
  } else if (type === 'TINYINT') {
761
761
  str += '(4)';
762
762
  } else if (type === 'DECIMAL') {
763
- str += `(${options.precision || 10}, ${options.length || 6})`;
763
+ str += `(${options.precision || 10}, ${options.scale || options.length || 6})`;
764
764
  }
765
765
  if (options.allowNull === false || options.primaryKey === true) {
766
766
  str += ' NOT NULL';
@@ -1,14 +0,0 @@
1
- {
2
- "recommendations": [
3
- "vscode-icons-team.vscode-icons",
4
- "formulahendry.docker-extension-pack",
5
- "mikestead.dotenv",
6
- "dbaeumer.vscode-eslint",
7
- "codezombiech.gitignore",
8
- "eamodio.gitlens",
9
- "esbenp.prettier-vscode",
10
- "wayou.vscode-todo-highlight",
11
- "octref.vetur",
12
- "pflannery.vscode-versionlens"
13
- ]
14
- }
@@ -1,5 +0,0 @@
1
- {
2
- "cSpell.words": [
3
- "fulltext"
4
- ]
5
- }
package/dist/orm-mysql DELETED
Binary file
@@ -1,18 +0,0 @@
1
- version: '3'
2
- # Settings and configurations that are common for all containers
3
- services:
4
- mysql:
5
- image: 'mysql:8.0'
6
- container_name: "orm-feature-tests-mysql"
7
- command: mysqld --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
8
- environment:
9
- MYSQL_ROOT_PASSWORD: '3AQqZTfmww=Ftj'
10
- MYSQL_DATABASE: 'feature_tests'
11
- restart: 'always'
12
- ports:
13
- - "3306:3306"
14
- healthcheck:
15
- test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p3AQqZTfmww=Ftj"]
16
- interval: 5s
17
- timeout: 3s
18
- retries: 10
@@ -1,28 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * @returns {Record<string, import('@axiosleo/orm-mysql').ColumnItem>}
5
- */
6
- module.exports = {
7
- id: {
8
- type: 'int',
9
- allowNull: false,
10
- primaryKey: true,
11
- autoIncrement: true
12
- },
13
- created_at: {
14
- type: 'TIMESTAMP',
15
- allowNull: false,
16
- default: 'CURRENT_TIMESTAMP'
17
- },
18
- updated_at: {
19
- type: 'TIMESTAMP',
20
- allowNull: false,
21
- default: 'CURRENT_TIMESTAMP',
22
- onUpdate: 'CURRENT_TIMESTAMP'
23
- },
24
- disabled_at: {
25
- type: 'TIMESTAMP',
26
- allowNull: true
27
- }
28
- };
@@ -1,16 +0,0 @@
1
- 'use strict';
2
-
3
- const path = require('path');
4
-
5
- const dotenv = require('dotenv');
6
- dotenv.config({
7
- path: path.join(__dirname, '../../../.env')
8
- });
9
-
10
- module.exports = {
11
- host: process.env.MYSQL_HOST,
12
- port: process.env.MYSQL_PORT,
13
- user: process.env.MYSQL_USER,
14
- password: process.env.MYSQL_PASS,
15
- database: process.env.MYSQL_DB
16
- };
@@ -1,108 +0,0 @@
1
- 'use strict';
2
-
3
- const baseColumn = require('../base_column');
4
-
5
- /**
6
- * @param {import('@axiosleo/orm-mysql').MigrationInterface} migration
7
- */
8
- function up(migration) {
9
- migration.createTable('orgs', {
10
- ...baseColumn,
11
- code: {
12
- type: 'varchar',
13
- length: 64,
14
- allowNull: false,
15
- uniqIndex: true
16
- },
17
- name: {
18
- type: 'VARCHAR',
19
- allowNull: false
20
- },
21
- type: {
22
- type: 'VARCHAR',
23
- comment: '集团 group;公司 company;',
24
- allowNull: false
25
- },
26
- });
27
-
28
- migration.createTable('account', {
29
- ...baseColumn,
30
- uuid: {
31
- type: 'VARCHAR',
32
- length: 36,
33
- allowNull: false,
34
- uniqIndex: true,
35
- comment: 'uuid'
36
- },
37
- username: {
38
- type: 'varchar',
39
- length: 64,
40
- allowNull: false,
41
- },
42
- name: {
43
- type: 'VARCHAR',
44
- length: 100,
45
- allowNull: false,
46
- comment: '姓名',
47
- },
48
- avatar: {
49
- type: 'VARCHAR',
50
- allowNull: true,
51
- comment: '头像文件索引'
52
- },
53
- password: {
54
- type: 'varchar',
55
- length: 64,
56
- allowNull: false
57
- },
58
- last_token: {
59
- type: 'VARCHAR',
60
- length: 36,
61
- allowNull: true,
62
- comment: '最后一次登录的token'
63
- }
64
- });
65
- migration.createIndex('account', ['username asc']);
66
-
67
- migration.createTable('account_orgs', {
68
- id: baseColumn.id,
69
- account_id: {
70
- type: 'int',
71
- allowNull: false,
72
- references: {
73
- table: 'account',
74
- column: 'id'
75
- }
76
- },
77
- org_id: {
78
- type: 'int',
79
- allowNull: false,
80
- references: {
81
- table: 'orgs',
82
- column: 'id'
83
- }
84
- },
85
- type: {
86
- type: 'varchar',
87
- length: 32,
88
- allowNull: false,
89
- comment: '组织创建者creator;组织管理员admin;组织用户user;',
90
- default: 'user'
91
- }
92
- });
93
- migration.createColumn('created_at', 'TIMESTAMP', 'account_orgs');
94
- }
95
-
96
- /**
97
- * @param {import('@axiosleo/orm-mysql').MigrationInterface} migration
98
- */
99
- function down(migration) {
100
- migration.dropTable('account_orgs');
101
- migration.dropTable('account');
102
- migration.dropTable('orgs');
103
- }
104
-
105
- module.exports = {
106
- up,
107
- down
108
- };
@@ -1,228 +0,0 @@
1
- /* eslint-disable no-console */
2
- 'use strict';
3
-
4
- /**
5
- * 事务使用示例
6
- *
7
- * 这个示例展示了如何正确使用事务,避免连接阻塞问题
8
- */
9
-
10
- const mysql = require('mysql2/promise');
11
- const { QueryHandler } = require('../src/operator');
12
-
13
- /**
14
- * 示例 1: 使用连接池(推荐)
15
- * 优点:自动从池中获取新连接,不会阻塞其他操作
16
- */
17
- async function exampleWithPool() {
18
- const pool = mysql.createPool({
19
- host: 'localhost',
20
- port: 3306,
21
- user: 'root',
22
- password: 'password',
23
- database: 'test_db',
24
- connectionLimit: 10
25
- });
26
-
27
- const queryHandler = new QueryHandler(pool);
28
-
29
- try {
30
- // 方式 1: 使用 QueryHandler.beginTransaction()(推荐)
31
- // 这会自动从连接池获取一个新连接用于事务
32
- const transaction = await queryHandler.beginTransaction({ level: 'RC' });
33
-
34
- try {
35
- // 执行事务操作
36
- await transaction.table('users').insert({ name: 'John', age: 30 });
37
- await transaction.table('orders').insert({ user_id: 1, total: 100 });
38
-
39
- // 提交事务(会自动释放连接回池)
40
- await transaction.commit();
41
- console.log('Transaction committed successfully');
42
- } catch (err) {
43
- // 回滚事务(会自动释放连接回池)
44
- await transaction.rollback();
45
- console.error('Transaction rolled back:', err.message);
46
- throw err;
47
- }
48
-
49
- // 同时,其他操作不会被阻塞
50
- const users = await queryHandler.table('users').select();
51
- console.log('Users:', users);
52
-
53
- } finally {
54
- await pool.end();
55
- }
56
- }
57
-
58
- /**
59
- * 示例 2: 使用单一连接(不推荐用于生产环境)
60
- * 注意:事务执行期间会阻塞该连接的其他操作
61
- */
62
- async function exampleWithSingleConnection() {
63
- const connection = await mysql.createConnection({
64
- host: 'localhost',
65
- port: 3306,
66
- user: 'root',
67
- password: 'password',
68
- database: 'test_db'
69
- });
70
-
71
- const queryHandler = new QueryHandler(connection);
72
-
73
- try {
74
- // 使用单一连接创建事务
75
- const transaction = await queryHandler.beginTransaction({ level: 'RR' });
76
-
77
- try {
78
- await transaction.table('users').insert({ name: 'Jane', age: 25 });
79
- await transaction.commit();
80
- console.log('Transaction committed');
81
- } catch (err) {
82
- await transaction.rollback();
83
- console.error('Transaction rolled back:', err);
84
- throw err;
85
- }
86
-
87
- } finally {
88
- await connection.end();
89
- }
90
- }
91
-
92
- /**
93
- * 示例 3: 直接使用 TransactionHandler
94
- * 适用于需要更多控制的场景
95
- */
96
- async function exampleWithTransactionHandler() {
97
- const { TransactionHandler } = require('../src/transaction');
98
-
99
- const connection = await mysql.createConnection({
100
- host: 'localhost',
101
- port: 3306,
102
- user: 'root',
103
- password: 'password',
104
- database: 'test_db'
105
- });
106
-
107
- const transaction = new TransactionHandler(connection, { level: 'SERIALIZABLE' });
108
-
109
- try {
110
- await transaction.begin();
111
-
112
- // 执行多个操作
113
- await transaction.table('users').insert({ name: 'Bob', age: 35 });
114
- await transaction.table('user_profiles').insert({ user_id: 1, bio: 'Developer' });
115
-
116
- // 使用锁
117
- const lockedRows = await transaction.table('products')
118
- .where('id', [1, 2, 3], 'IN')
119
- .append('FOR UPDATE')
120
- .select();
121
-
122
- console.log('Locked rows:', lockedRows);
123
-
124
- await transaction.commit();
125
- console.log('Transaction completed');
126
- } catch (err) {
127
- await transaction.rollback();
128
- console.error('Error:', err);
129
- throw err;
130
- } finally {
131
- await connection.end();
132
- }
133
- }
134
-
135
- /**
136
- * 示例 4: 并发事务(使用连接池)
137
- * 展示多个事务可以同时执行而不相互阻塞
138
- */
139
- async function exampleConcurrentTransactions() {
140
- const pool = mysql.createPool({
141
- host: 'localhost',
142
- port: 3306,
143
- user: 'root',
144
- password: 'password',
145
- database: 'test_db',
146
- connectionLimit: 10
147
- });
148
-
149
- const queryHandler = new QueryHandler(pool);
150
-
151
- try {
152
- // 并发执行多个事务
153
- const results = await Promise.all([
154
- // 事务 1
155
- (async () => {
156
- const tx = await queryHandler.beginTransaction();
157
- try {
158
- await tx.table('users').insert({ name: 'User1', age: 20 });
159
- await tx.commit();
160
- return 'Transaction 1 completed';
161
- } catch (err) {
162
- await tx.rollback();
163
- throw err;
164
- }
165
- })(),
166
-
167
- // 事务 2
168
- (async () => {
169
- const tx = await queryHandler.beginTransaction();
170
- try {
171
- await tx.table('users').insert({ name: 'User2', age: 21 });
172
- await tx.commit();
173
- return 'Transaction 2 completed';
174
- } catch (err) {
175
- await tx.rollback();
176
- throw err;
177
- }
178
- })(),
179
-
180
- // 事务 3
181
- (async () => {
182
- const tx = await queryHandler.beginTransaction();
183
- try {
184
- await tx.table('users').insert({ name: 'User3', age: 22 });
185
- await tx.commit();
186
- return 'Transaction 3 completed';
187
- } catch (err) {
188
- await tx.rollback();
189
- throw err;
190
- }
191
- })()
192
- ]);
193
-
194
- console.log('All transactions completed:', results);
195
- } finally {
196
- await pool.end();
197
- }
198
- }
199
-
200
- /**
201
- * 最佳实践总结:
202
- *
203
- * 1. 生产环境推荐使用连接池(Pool)
204
- * 2. 使用 QueryHandler.beginTransaction() 自动管理连接
205
- * 3. 始终在 try-catch-finally 中使用事务
206
- * 4. 确保调用 commit() 或 rollback()
207
- * 5. 连接池会自动释放连接,无需手动管理
208
- * 6. 避免在事务中执行长时间运行的操作
209
- * 7. 根据需要选择合适的隔离级别:
210
- * - 'RU' / 'READ UNCOMMITTED': 最低隔离级别,性能最好,可能读到脏数据
211
- * - 'RC' / 'READ COMMITTED': 避免脏读
212
- * - 'RR' / 'REPEATABLE READ': MySQL 默认级别,避免不可重复读
213
- * - 'S' / 'SERIALIZABLE': 最高隔离级别,完全串行化,性能最差
214
- */
215
-
216
- // 运行示例(取消注释以运行)
217
- // exampleWithPool().catch(console.error);
218
- // exampleWithSingleConnection().catch(console.error);
219
- // exampleWithTransactionHandler().catch(console.error);
220
- // exampleConcurrentTransactions().catch(console.error);
221
-
222
- module.exports = {
223
- exampleWithPool,
224
- exampleWithSingleConnection,
225
- exampleWithTransactionHandler,
226
- exampleConcurrentTransactions
227
- };
228
-
@@ -1,5 +0,0 @@
1
- ignoredBuiltDependencies:
2
- - pre-commit
3
-
4
- onlyBuiltDependencies:
5
- - spawn-sync