@fuzionx/framework 0.1.43 → 0.1.45
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/README.md +501 -501
- package/bin/fx.js +12 -12
- package/cli/db-sync.js +100 -100
- package/cli/index.js +494 -494
- package/cli/templates/make/app/controllers/HomeController.js +14 -14
- package/cli/templates/make/app/routes/api.js +7 -7
- package/cli/templates/make/app/routes/web.js +5 -5
- package/cli/templates/make/app/views/default/errors/404.html +11 -11
- package/cli/templates/make/app/views/default/errors/500.html +14 -14
- package/cli/templates/make/app/views/default/layouts/main.html +22 -22
- package/cli/templates/make/app/views/default/pages/home.html +11 -11
- package/cli/templates/make/controller.js.tpl +40 -40
- package/cli/templates/make/event.js.tpl +8 -8
- package/cli/templates/make/job.js.tpl +10 -10
- package/cli/templates/make/middleware.js.tpl +10 -10
- package/cli/templates/make/model.js.tpl +15 -15
- package/cli/templates/make/service.js.tpl +15 -15
- package/cli/templates/make/task.js.tpl +15 -15
- package/cli/templates/make/test.js.tpl +7 -7
- package/cli/templates/make/worker.js.tpl +14 -14
- package/cli/templates/make/ws.js.tpl +18 -18
- package/index.js +67 -67
- package/lib/core/AppError.js +46 -46
- package/lib/core/Application.js +1006 -1006
- package/lib/core/AutoLoader.js +227 -227
- package/lib/core/Base.js +64 -64
- package/lib/core/Config.js +331 -331
- package/lib/core/Context.js +484 -484
- package/lib/database/ConnectionManager.js +208 -208
- package/lib/database/MariaModel.js +29 -29
- package/lib/database/Model.js +247 -247
- package/lib/database/ModelRegistry.js +72 -72
- package/lib/database/MongoModel.js +232 -232
- package/lib/database/Pagination.js +37 -37
- package/lib/database/PostgreModel.js +29 -29
- package/lib/database/QueryBuilder.js +172 -172
- package/lib/database/SQLiteModel.js +27 -27
- package/lib/database/SqlModel.js +257 -257
- package/lib/database/SqlQueryBuilder.js +332 -332
- package/lib/helpers/CryptoHelper.js +48 -48
- package/lib/helpers/FileHelper.js +61 -61
- package/lib/helpers/HashHelper.js +39 -39
- package/lib/helpers/I18nHelper.js +174 -174
- package/lib/helpers/Logger.js +108 -108
- package/lib/helpers/MediaHelper.js +84 -84
- package/lib/http/Controller.js +34 -34
- package/lib/http/ErrorHandler.js +136 -136
- package/lib/http/Middleware.js +43 -43
- package/lib/http/Router.js +109 -109
- package/lib/http/Validation.js +125 -125
- package/lib/middleware/apiAuth.js +79 -79
- package/lib/middleware/auth.js +42 -42
- package/lib/middleware/bodyParser.js +19 -19
- package/lib/middleware/cors.js +47 -47
- package/lib/middleware/csrf.js +32 -32
- package/lib/middleware/index.js +13 -13
- package/lib/middleware/session.js +27 -27
- package/lib/middleware/theme.js +20 -20
- package/lib/realtime/RoomManager.js +85 -85
- package/lib/realtime/WsHandler.js +107 -107
- package/lib/schedule/Job.js +38 -38
- package/lib/schedule/Queue.js +103 -103
- package/lib/schedule/Scheduler.js +171 -171
- package/lib/schedule/Task.js +39 -39
- package/lib/schedule/WorkerPool.js +225 -225
- package/lib/services/EventBus.js +94 -94
- package/lib/services/Service.js +261 -261
- package/lib/services/Storage.js +112 -112
- package/lib/utilities/ArrUtil.js +112 -112
- package/lib/utilities/DateUtil.js +98 -98
- package/lib/utilities/FunctionUtil.js +119 -119
- package/lib/utilities/NumUtil.js +75 -75
- package/lib/utilities/ObjectUtil.js +170 -170
- package/lib/utilities/PaginationUtil.js +81 -81
- package/lib/utilities/StrUtil.js +105 -105
- package/lib/utilities/index.js +18 -18
- package/lib/view/OpenAPI.js +231 -231
- package/lib/view/View.js +83 -83
- package/package.json +2 -2
- package/testing/index.js +232 -232
|
@@ -1,208 +1,208 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ConnectionManager — DB 연결 관리 싱글톤
|
|
3
|
-
*
|
|
4
|
-
* 드라이버별 연결 생성/캐싱/종료.
|
|
5
|
-
* SQLite (기본), MariaDB, PostgreSQL, MongoDB 지원.
|
|
6
|
-
*
|
|
7
|
-
* @see docs/framework/02-database-orm.md
|
|
8
|
-
* @see docs/framework/17-config.md
|
|
9
|
-
*/
|
|
10
|
-
import { createRequire } from 'node:module';
|
|
11
|
-
|
|
12
|
-
const _require = createRequire(import.meta.url);
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* optional dependency 안전 로드
|
|
16
|
-
* @private
|
|
17
|
-
*/
|
|
18
|
-
function tryRequire(name) {
|
|
19
|
-
try { return _require(name); } catch { return null; }
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export default class ConnectionManager {
|
|
23
|
-
constructor() {
|
|
24
|
-
/** @type {Map<string, object>} name → connection */
|
|
25
|
-
this._connections = new Map();
|
|
26
|
-
/** @type {Map<string, object>} name → config */
|
|
27
|
-
this._configs = new Map();
|
|
28
|
-
/** @type {string} default connection name */
|
|
29
|
-
this._default = 'main';
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* 설정으로 초기화
|
|
34
|
-
* @param {object} dbConfig - fuzionx.yaml database 섹션
|
|
35
|
-
*/
|
|
36
|
-
configure(dbConfig) {
|
|
37
|
-
this._default = dbConfig.default || 'main';
|
|
38
|
-
const connections = dbConfig.connections || {};
|
|
39
|
-
for (const [name, cfg] of Object.entries(connections)) {
|
|
40
|
-
this._configs.set(name, cfg);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* 연결 가져오기 (lazy 생성)
|
|
46
|
-
* @param {string} [name] - connection name (default: _default)
|
|
47
|
-
* @returns {object} driver connection instance
|
|
48
|
-
*/
|
|
49
|
-
get(name) {
|
|
50
|
-
const connName = name || this._default;
|
|
51
|
-
if (this._connections.has(connName)) {
|
|
52
|
-
return this._connections.get(connName);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const config = this._configs.get(connName);
|
|
56
|
-
if (!config) {
|
|
57
|
-
throw new Error(`DB connection '${connName}' not configured. Check fuzionx.yaml database.connections.`);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const conn = this._createConnection(connName, config);
|
|
61
|
-
this._connections.set(connName, conn);
|
|
62
|
-
return conn;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* 드라이버 타입 조회
|
|
67
|
-
* @param {string} [name]
|
|
68
|
-
* @returns {string} 'sqlite' | 'mariadb' | 'postgres' | 'mongodb'
|
|
69
|
-
*/
|
|
70
|
-
getDriver(name) {
|
|
71
|
-
const connName = name || this._default;
|
|
72
|
-
const config = this._configs.get(connName);
|
|
73
|
-
return config?.driver || 'sqlite';
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* 드라이버별 연결 생성
|
|
78
|
-
* @private
|
|
79
|
-
*/
|
|
80
|
-
_createConnection(name, config) {
|
|
81
|
-
const driver = (config.driver || 'sqlite').toLowerCase();
|
|
82
|
-
|
|
83
|
-
switch (driver) {
|
|
84
|
-
case 'sqlite': {
|
|
85
|
-
const Database = tryRequire('better-sqlite3');
|
|
86
|
-
if (!Database) return this._createStub('sqlite', config);
|
|
87
|
-
|
|
88
|
-
const dbPath = config.database || config.path || ':memory:';
|
|
89
|
-
const db = new Database(dbPath, {
|
|
90
|
-
verbose: config.verbose ? console.log : undefined,
|
|
91
|
-
});
|
|
92
|
-
db.pragma('journal_mode = WAL');
|
|
93
|
-
db.pragma('foreign_keys = ON');
|
|
94
|
-
return { type: 'sqlite', db, config };
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
case 'mariadb':
|
|
98
|
-
case 'mysql': {
|
|
99
|
-
const knex = tryRequire('knex');
|
|
100
|
-
if (!knex) return this._createStub('knex', config, 'mariadb');
|
|
101
|
-
|
|
102
|
-
const knexInit = typeof knex === 'function' ? knex : knex.default;
|
|
103
|
-
const db = knexInit({
|
|
104
|
-
client: 'mysql2',
|
|
105
|
-
connection: {
|
|
106
|
-
host: config.host || '127.0.0.1',
|
|
107
|
-
port: config.port || 3306,
|
|
108
|
-
user: config.user || 'root',
|
|
109
|
-
password: config.password || '',
|
|
110
|
-
database: config.database || '',
|
|
111
|
-
charset: config.charset || 'utf8mb4',
|
|
112
|
-
},
|
|
113
|
-
pool: config.pool || { min: 2, max: 10 },
|
|
114
|
-
});
|
|
115
|
-
return { type: 'knex', driver: 'mariadb', db, config };
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
case 'postgres':
|
|
119
|
-
case 'postgresql': {
|
|
120
|
-
const knex = tryRequire('knex');
|
|
121
|
-
if (!knex) return this._createStub('knex', config, 'postgres');
|
|
122
|
-
|
|
123
|
-
const knexInit = typeof knex === 'function' ? knex : knex.default;
|
|
124
|
-
const db = knexInit({
|
|
125
|
-
client: 'pg',
|
|
126
|
-
connection: {
|
|
127
|
-
host: config.host || '127.0.0.1',
|
|
128
|
-
port: config.port || 5432,
|
|
129
|
-
user: config.user || 'postgres',
|
|
130
|
-
password: config.password || '',
|
|
131
|
-
database: config.database || '',
|
|
132
|
-
},
|
|
133
|
-
pool: config.pool || { min: 2, max: 10 },
|
|
134
|
-
});
|
|
135
|
-
return { type: 'knex', driver: 'postgres', db, config };
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
case 'mongodb':
|
|
139
|
-
case 'mongo': {
|
|
140
|
-
const mongoose = tryRequire('mongoose');
|
|
141
|
-
if (!mongoose) return this._createStub('mongo', config);
|
|
142
|
-
// Lazy connect — promise 캐싱으로 이중 연결 방지
|
|
143
|
-
const conn = { type: 'mongo', mongoose, config, _connected: false, _connectPromise: null };
|
|
144
|
-
conn.connect = () => {
|
|
145
|
-
if (conn._connected) return Promise.resolve();
|
|
146
|
-
if (conn._connectPromise) return conn._connectPromise;
|
|
147
|
-
const uri = config.uri || config.url
|
|
148
|
-
|| `mongodb://${config.host || '127.0.0.1'}:${config.port || 27017}/${config.database || ''}`;
|
|
149
|
-
conn._connectPromise = mongoose.connect(uri, config.options || {}).then(() => {
|
|
150
|
-
conn._connected = true;
|
|
151
|
-
});
|
|
152
|
-
return conn._connectPromise;
|
|
153
|
-
};
|
|
154
|
-
// 즉시 연결 시작 (await 없이 — 백그라운드)
|
|
155
|
-
conn.connect().catch(err => {
|
|
156
|
-
console.error(`[ConnectionManager] MongoDB 연결 실패: ${err.message}`);
|
|
157
|
-
});
|
|
158
|
-
return conn;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
default:
|
|
162
|
-
throw new Error(`Unsupported DB driver: '${driver}'. Supported: sqlite, mariadb, postgres, mongodb.`);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* 드라이버 미설치 stub
|
|
168
|
-
* @private
|
|
169
|
-
*/
|
|
170
|
-
_createStub(type, config, driver) {
|
|
171
|
-
return { type, driver: driver || type, db: null, config, _stub: true };
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* 모든 연결 종료 (graceful shutdown)
|
|
176
|
-
*/
|
|
177
|
-
async closeAll() {
|
|
178
|
-
for (const [name, conn] of this._connections) {
|
|
179
|
-
try {
|
|
180
|
-
if (conn.type === 'sqlite' && conn.db) {
|
|
181
|
-
conn.db.close();
|
|
182
|
-
} else if (conn.type === 'knex' && conn.db) {
|
|
183
|
-
await conn.db.destroy();
|
|
184
|
-
} else if (conn.type === 'mongo' && conn.mongoose) {
|
|
185
|
-
await conn.mongoose.disconnect();
|
|
186
|
-
}
|
|
187
|
-
} catch (err) {
|
|
188
|
-
console.error(`[ConnectionManager] Error closing '${name}':`, err.message);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
this._connections.clear();
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* 특정 연결 종료
|
|
196
|
-
* @param {string} name
|
|
197
|
-
*/
|
|
198
|
-
async close(name) {
|
|
199
|
-
const conn = this._connections.get(name);
|
|
200
|
-
if (!conn) return;
|
|
201
|
-
try {
|
|
202
|
-
if (conn.type === 'sqlite' && conn.db) conn.db.close();
|
|
203
|
-
else if (conn.type === 'knex' && conn.db) await conn.db.destroy();
|
|
204
|
-
else if (conn.type === 'mongo' && conn.mongoose) await conn.mongoose.disconnect();
|
|
205
|
-
} catch {}
|
|
206
|
-
this._connections.delete(name);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* ConnectionManager — DB 연결 관리 싱글톤
|
|
3
|
+
*
|
|
4
|
+
* 드라이버별 연결 생성/캐싱/종료.
|
|
5
|
+
* SQLite (기본), MariaDB, PostgreSQL, MongoDB 지원.
|
|
6
|
+
*
|
|
7
|
+
* @see docs/framework/02-database-orm.md
|
|
8
|
+
* @see docs/framework/17-config.md
|
|
9
|
+
*/
|
|
10
|
+
import { createRequire } from 'node:module';
|
|
11
|
+
|
|
12
|
+
const _require = createRequire(import.meta.url);
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* optional dependency 안전 로드
|
|
16
|
+
* @private
|
|
17
|
+
*/
|
|
18
|
+
function tryRequire(name) {
|
|
19
|
+
try { return _require(name); } catch { return null; }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default class ConnectionManager {
|
|
23
|
+
constructor() {
|
|
24
|
+
/** @type {Map<string, object>} name → connection */
|
|
25
|
+
this._connections = new Map();
|
|
26
|
+
/** @type {Map<string, object>} name → config */
|
|
27
|
+
this._configs = new Map();
|
|
28
|
+
/** @type {string} default connection name */
|
|
29
|
+
this._default = 'main';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 설정으로 초기화
|
|
34
|
+
* @param {object} dbConfig - fuzionx.yaml database 섹션
|
|
35
|
+
*/
|
|
36
|
+
configure(dbConfig) {
|
|
37
|
+
this._default = dbConfig.default || 'main';
|
|
38
|
+
const connections = dbConfig.connections || {};
|
|
39
|
+
for (const [name, cfg] of Object.entries(connections)) {
|
|
40
|
+
this._configs.set(name, cfg);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 연결 가져오기 (lazy 생성)
|
|
46
|
+
* @param {string} [name] - connection name (default: _default)
|
|
47
|
+
* @returns {object} driver connection instance
|
|
48
|
+
*/
|
|
49
|
+
get(name) {
|
|
50
|
+
const connName = name || this._default;
|
|
51
|
+
if (this._connections.has(connName)) {
|
|
52
|
+
return this._connections.get(connName);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const config = this._configs.get(connName);
|
|
56
|
+
if (!config) {
|
|
57
|
+
throw new Error(`DB connection '${connName}' not configured. Check fuzionx.yaml database.connections.`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const conn = this._createConnection(connName, config);
|
|
61
|
+
this._connections.set(connName, conn);
|
|
62
|
+
return conn;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 드라이버 타입 조회
|
|
67
|
+
* @param {string} [name]
|
|
68
|
+
* @returns {string} 'sqlite' | 'mariadb' | 'postgres' | 'mongodb'
|
|
69
|
+
*/
|
|
70
|
+
getDriver(name) {
|
|
71
|
+
const connName = name || this._default;
|
|
72
|
+
const config = this._configs.get(connName);
|
|
73
|
+
return config?.driver || 'sqlite';
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* 드라이버별 연결 생성
|
|
78
|
+
* @private
|
|
79
|
+
*/
|
|
80
|
+
_createConnection(name, config) {
|
|
81
|
+
const driver = (config.driver || 'sqlite').toLowerCase();
|
|
82
|
+
|
|
83
|
+
switch (driver) {
|
|
84
|
+
case 'sqlite': {
|
|
85
|
+
const Database = tryRequire('better-sqlite3');
|
|
86
|
+
if (!Database) return this._createStub('sqlite', config);
|
|
87
|
+
|
|
88
|
+
const dbPath = config.database || config.path || ':memory:';
|
|
89
|
+
const db = new Database(dbPath, {
|
|
90
|
+
verbose: config.verbose ? console.log : undefined,
|
|
91
|
+
});
|
|
92
|
+
db.pragma('journal_mode = WAL');
|
|
93
|
+
db.pragma('foreign_keys = ON');
|
|
94
|
+
return { type: 'sqlite', db, config };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
case 'mariadb':
|
|
98
|
+
case 'mysql': {
|
|
99
|
+
const knex = tryRequire('knex');
|
|
100
|
+
if (!knex) return this._createStub('knex', config, 'mariadb');
|
|
101
|
+
|
|
102
|
+
const knexInit = typeof knex === 'function' ? knex : knex.default;
|
|
103
|
+
const db = knexInit({
|
|
104
|
+
client: 'mysql2',
|
|
105
|
+
connection: {
|
|
106
|
+
host: config.host || '127.0.0.1',
|
|
107
|
+
port: config.port || 3306,
|
|
108
|
+
user: config.user || 'root',
|
|
109
|
+
password: config.password || '',
|
|
110
|
+
database: config.database || '',
|
|
111
|
+
charset: config.charset || 'utf8mb4',
|
|
112
|
+
},
|
|
113
|
+
pool: config.pool || { min: 2, max: 10 },
|
|
114
|
+
});
|
|
115
|
+
return { type: 'knex', driver: 'mariadb', db, config };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
case 'postgres':
|
|
119
|
+
case 'postgresql': {
|
|
120
|
+
const knex = tryRequire('knex');
|
|
121
|
+
if (!knex) return this._createStub('knex', config, 'postgres');
|
|
122
|
+
|
|
123
|
+
const knexInit = typeof knex === 'function' ? knex : knex.default;
|
|
124
|
+
const db = knexInit({
|
|
125
|
+
client: 'pg',
|
|
126
|
+
connection: {
|
|
127
|
+
host: config.host || '127.0.0.1',
|
|
128
|
+
port: config.port || 5432,
|
|
129
|
+
user: config.user || 'postgres',
|
|
130
|
+
password: config.password || '',
|
|
131
|
+
database: config.database || '',
|
|
132
|
+
},
|
|
133
|
+
pool: config.pool || { min: 2, max: 10 },
|
|
134
|
+
});
|
|
135
|
+
return { type: 'knex', driver: 'postgres', db, config };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
case 'mongodb':
|
|
139
|
+
case 'mongo': {
|
|
140
|
+
const mongoose = tryRequire('mongoose');
|
|
141
|
+
if (!mongoose) return this._createStub('mongo', config);
|
|
142
|
+
// Lazy connect — promise 캐싱으로 이중 연결 방지
|
|
143
|
+
const conn = { type: 'mongo', mongoose, config, _connected: false, _connectPromise: null };
|
|
144
|
+
conn.connect = () => {
|
|
145
|
+
if (conn._connected) return Promise.resolve();
|
|
146
|
+
if (conn._connectPromise) return conn._connectPromise;
|
|
147
|
+
const uri = config.uri || config.url
|
|
148
|
+
|| `mongodb://${config.host || '127.0.0.1'}:${config.port || 27017}/${config.database || ''}`;
|
|
149
|
+
conn._connectPromise = mongoose.connect(uri, config.options || {}).then(() => {
|
|
150
|
+
conn._connected = true;
|
|
151
|
+
});
|
|
152
|
+
return conn._connectPromise;
|
|
153
|
+
};
|
|
154
|
+
// 즉시 연결 시작 (await 없이 — 백그라운드)
|
|
155
|
+
conn.connect().catch(err => {
|
|
156
|
+
console.error(`[ConnectionManager] MongoDB 연결 실패: ${err.message}`);
|
|
157
|
+
});
|
|
158
|
+
return conn;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
default:
|
|
162
|
+
throw new Error(`Unsupported DB driver: '${driver}'. Supported: sqlite, mariadb, postgres, mongodb.`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* 드라이버 미설치 stub
|
|
168
|
+
* @private
|
|
169
|
+
*/
|
|
170
|
+
_createStub(type, config, driver) {
|
|
171
|
+
return { type, driver: driver || type, db: null, config, _stub: true };
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* 모든 연결 종료 (graceful shutdown)
|
|
176
|
+
*/
|
|
177
|
+
async closeAll() {
|
|
178
|
+
for (const [name, conn] of this._connections) {
|
|
179
|
+
try {
|
|
180
|
+
if (conn.type === 'sqlite' && conn.db) {
|
|
181
|
+
conn.db.close();
|
|
182
|
+
} else if (conn.type === 'knex' && conn.db) {
|
|
183
|
+
await conn.db.destroy();
|
|
184
|
+
} else if (conn.type === 'mongo' && conn.mongoose) {
|
|
185
|
+
await conn.mongoose.disconnect();
|
|
186
|
+
}
|
|
187
|
+
} catch (err) {
|
|
188
|
+
console.error(`[ConnectionManager] Error closing '${name}':`, err.message);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
this._connections.clear();
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* 특정 연결 종료
|
|
196
|
+
* @param {string} name
|
|
197
|
+
*/
|
|
198
|
+
async close(name) {
|
|
199
|
+
const conn = this._connections.get(name);
|
|
200
|
+
if (!conn) return;
|
|
201
|
+
try {
|
|
202
|
+
if (conn.type === 'sqlite' && conn.db) conn.db.close();
|
|
203
|
+
else if (conn.type === 'knex' && conn.db) await conn.db.destroy();
|
|
204
|
+
else if (conn.type === 'mongo' && conn.mongoose) await conn.mongoose.disconnect();
|
|
205
|
+
} catch {}
|
|
206
|
+
this._connections.delete(name);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MariaModel — MariaDB/MySQL 모델 서브클래스
|
|
3
|
-
*
|
|
4
|
-
* Knex + mysql2 기반.
|
|
5
|
-
* SqlModel의 공통 SQL 로직을 상속하며,
|
|
6
|
-
* MariaDB 고유 기능(FULLTEXT, JSON 등)은 raw()로 접근.
|
|
7
|
-
*
|
|
8
|
-
* @see docs/framework/02-database-orm.md
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* import { MariaModel } from '@fuzionx/framework';
|
|
12
|
-
*
|
|
13
|
-
* export default class User extends MariaModel {
|
|
14
|
-
* static table = 'users';
|
|
15
|
-
* static connection = 'main';
|
|
16
|
-
* static timestamps = true;
|
|
17
|
-
* static columns = {
|
|
18
|
-
* id: { type: 'increments' },
|
|
19
|
-
* name: { type: 'string', length: 100 },
|
|
20
|
-
* email: { type: 'string', length: 150, unique: true },
|
|
21
|
-
* };
|
|
22
|
-
* }
|
|
23
|
-
*/
|
|
24
|
-
import SqlModel from './SqlModel.js';
|
|
25
|
-
|
|
26
|
-
export default class MariaModel extends SqlModel {
|
|
27
|
-
static driver = 'mariadb';
|
|
28
|
-
static connection = 'main';
|
|
29
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* MariaModel — MariaDB/MySQL 모델 서브클래스
|
|
3
|
+
*
|
|
4
|
+
* Knex + mysql2 기반.
|
|
5
|
+
* SqlModel의 공통 SQL 로직을 상속하며,
|
|
6
|
+
* MariaDB 고유 기능(FULLTEXT, JSON 등)은 raw()로 접근.
|
|
7
|
+
*
|
|
8
|
+
* @see docs/framework/02-database-orm.md
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* import { MariaModel } from '@fuzionx/framework';
|
|
12
|
+
*
|
|
13
|
+
* export default class User extends MariaModel {
|
|
14
|
+
* static table = 'users';
|
|
15
|
+
* static connection = 'main';
|
|
16
|
+
* static timestamps = true;
|
|
17
|
+
* static columns = {
|
|
18
|
+
* id: { type: 'increments' },
|
|
19
|
+
* name: { type: 'string', length: 100 },
|
|
20
|
+
* email: { type: 'string', length: 150, unique: true },
|
|
21
|
+
* };
|
|
22
|
+
* }
|
|
23
|
+
*/
|
|
24
|
+
import SqlModel from './SqlModel.js';
|
|
25
|
+
|
|
26
|
+
export default class MariaModel extends SqlModel {
|
|
27
|
+
static driver = 'mariadb';
|
|
28
|
+
static connection = 'main';
|
|
29
|
+
}
|