@gumin61/transfer-data-sdk 1.2.0 → 1.2.1
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 +165 -263
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,317 +1,219 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @gumin61/transfer-data-sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
SDK สำหรับโอนย้ายข้อมูลระหว่าง MySQL database (source → target) รองรับการ insert เฉพาะแถวใหม่ตาม PK, validation, restore user refs และจัดการ FK ที่ไม่มีในตารางอ้างอิง
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
หมายเหตุ: structure schema ของฐานข้อมูลปลายทาง(target) จะต้องเหมือนกับฐานข้อมูลต้นทาง(source)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## การติดตั้ง
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @gumin61/transfer-data-sdk mysql2
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## ความต้องการของระบบ
|
|
8
14
|
|
|
9
|
-
|
|
15
|
+
- Node.js 18+
|
|
16
|
+
- MySQL (ใช้ `mysql2` เป็น driver)
|
|
10
17
|
|
|
11
|
-
|
|
18
|
+
## การใช้งานพื้นฐาน
|
|
12
19
|
|
|
13
20
|
```ts
|
|
14
21
|
import mysql from "mysql2/promise";
|
|
15
22
|
import { copyDataTables } from "@gumin61/transfer-data-sdk";
|
|
16
23
|
|
|
17
|
-
const sourcePool = mysql.createPool({
|
|
18
|
-
|
|
24
|
+
const sourcePool = mysql.createPool({
|
|
25
|
+
host: "localhost",
|
|
26
|
+
port: 3306,
|
|
27
|
+
user: "root",
|
|
28
|
+
password: "password",
|
|
29
|
+
database: "source_db",
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const targetPool = mysql.createPool({
|
|
33
|
+
host: "localhost",
|
|
34
|
+
port: 3306,
|
|
35
|
+
user: "root",
|
|
36
|
+
password: "password",
|
|
37
|
+
database: "target_db",
|
|
38
|
+
});
|
|
19
39
|
|
|
20
40
|
const result = await copyDataTables(
|
|
21
41
|
{ sourcePool, targetPool },
|
|
22
42
|
{
|
|
23
|
-
tableNames: ["permissions"],
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
{ tableName: "systemlangaue", batchSize: 100 },
|
|
27
|
-
],
|
|
28
|
-
},
|
|
43
|
+
tableNames: ["users", "permissions"],
|
|
44
|
+
options: { pageSize: 500, batchSize: 500 },
|
|
45
|
+
}
|
|
29
46
|
);
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
- build SDK: `npm run build:sdk`
|
|
33
|
-
- ทดสอบตัวอย่างการใช้งาน SDK: `npm run demo:test`
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## 1. คำสั่ง npm ที่มีในโปรเจกต์
|
|
38
47
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
npm run table -- --name "<ชื่อตาราง>"
|
|
48
|
+
console.table(result.tableResults);
|
|
49
|
+
console.log(`Total: ${result.totalRowsTransferred} rows`);
|
|
43
50
|
```
|
|
44
51
|
|
|
45
|
-
|
|
46
|
-
|---------------|----------|
|
|
47
|
-
| `npm run table -- --name "permissions"` | โอนเฉพาะตาราง permissions (sync จาก v3) |
|
|
48
|
-
| `npm run table -- --name "users"` | โอนเฉพาะตาราง users |
|
|
49
|
-
| `npm run table -- --name "pii_master"` | โอนเฉพาะตาราง pii_master |
|
|
50
|
-
| `npm run table -- --name "organizations"` | โอนเฉพาะตาราง organizations |
|
|
51
|
-
|
|
52
|
-
- ตารางต้องอยู่ใน config ของ section ใด section หนึ่ง (`sections.config.ts`) จึงจะรันได้
|
|
53
|
-
|
|
54
|
-
---
|
|
55
|
-
|
|
56
|
-
### 1.2 รันโอนตาม Section
|
|
57
|
-
|
|
58
|
-
| คำสั่ง | ความหมาย |
|
|
59
|
-
|--------|----------|
|
|
60
|
-
| `npm run transfer:sections` | รันทุก section ตามลำดับ (section-1 → master-data → section-2 → … → section-6 → section-1 อีกครั้ง → section-7-1 → section-7-2) |
|
|
61
|
-
| `npm run transfer:section-1` | รันเฉพาะ Section 1 (Core Data) |
|
|
62
|
-
| `npm run transfer:section-2` | รันเฉพาะ Section 2 |
|
|
63
|
-
| `npm run transfer:section-3` | รันเฉพาะ Section 3 |
|
|
64
|
-
| `npm run transfer:section-4` | รันเฉพาะ Section 4 |
|
|
65
|
-
| `npm run transfer:section-5` | รันเฉพาะ Section 5 |
|
|
66
|
-
| `npm run transfer:section-6` | รันเฉพาะ Section 6 |
|
|
67
|
-
| `npm run transfer:master-data` | รันเฉพาะ Master Data |
|
|
68
|
-
| `npm run transfer:section-7` | รัน Section 7 ทั้งหมด (section-7-1 + section-7-2) |
|
|
69
|
-
| `npm run transfer:section-7-1` | รันเฉพาะ Section 7.1 |
|
|
70
|
-
| `npm run transfer:section-7-2` | รันเฉพาะ Section 7.2 (จำเป็นต้องรัน 7.1 ก่อน หากรันแล้วสามารถรันส่วนนี้ทันทีได้เลย) |
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
### 1.3 รันทดสอบและตรวจสอบข้อมูล (ส่วนนี้ต้องกำหนด Logic ที่จะตรวจสอบใน run-test.ts)
|
|
75
|
-
|
|
76
|
-
| คำสั่ง | ความหมาย |
|
|
77
|
-
|--------|----------|
|
|
78
|
-
| `npm run test -- --function "<function_name>"` | รันฟังก์ชันทดสอบที่กำหนด (เช่น `validate_permissions`, `validate_data`, `copy_tables`) |
|
|
79
|
-
| `npm run validate-data` | รันการตรวจสอบความถูกต้องของข้อมูล |
|
|
80
|
-
| `npm run seed:permissions` | seed/อัปเดตตาราง permissions จาก `src/assets/data/permissions.ts` (รันแยกหลัง section-1 ตามต้องการ) |
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
## 2. ลำดับการรันเมื่อใช้ `transfer:sections` (ไม่ควรข้าม section ใด section หนึ่ง)
|
|
85
|
-
|
|
86
|
-
1. **section-1** (Core Data – company, org, users, roles, permissions ฯลฯ)
|
|
87
|
-
2. **master-data** (Master tables – chanel_dsar, data_type_master ฯลฯ)
|
|
88
|
-
3. **section-2** (Owner, Activity, ROP ฯลฯ)
|
|
89
|
-
4. **section-3** (Consent)
|
|
90
|
-
5. **section-4** (DSAR)
|
|
91
|
-
6. **section-5** (Incident)
|
|
92
|
-
7. **section-6** (PDPA message, file attach ฯลฯ)
|
|
93
|
-
8. **section-1** อีกครั้ง (ถ้าต้องการ sync ข้อมูล core ซ้ำ)
|
|
94
|
-
9. **`npm run seed:permissions`** (อัปเดต permissions จาก assets/data/permissions.ts — รันแยกเมื่อต้องการ)
|
|
95
|
-
10. **section-7-1** (CK, Consent CK ฯลฯ)
|
|
96
|
-
11. **section-7-2** (Access, DSAR เพิ่มเติม, Technical measures ฯลฯ)
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
## 3. ตารางที่แต่ละ Section Insert และเงื่อนไขเพิ่มเติม
|
|
101
|
-
|
|
102
|
-
### Master Data (`master-data`)
|
|
103
|
-
|
|
104
|
-
**วิธีโอน:** ใช้ `copyTableMaster` — อ่านจาก source แล้ว insert ลง target โดยรันซ้ำจะ **insert เฉพาะแถวที่ PK ยังไม่มีใน target** (ไม่ insert ซ้ำ)
|
|
105
|
-
|
|
106
|
-
**ตารางที่ insert (ตามลำดับ):**
|
|
107
|
-
|
|
108
|
-
| ลำดับ | ชื่อตาราง |
|
|
109
|
-
|-------|------------|
|
|
110
|
-
| 1 | chanel_dsar_master |
|
|
111
|
-
| 2 | data_backup_location_master |
|
|
112
|
-
| 3 | disposal_data_type_master |
|
|
113
|
-
| 4 | encryption_type_master |
|
|
114
|
-
| 5 | subject_type_master |
|
|
115
|
-
| 6 | subject_group_master |
|
|
116
|
-
| 7 | rop_gap_type_master |
|
|
117
|
-
| 8 | rop_gap_master |
|
|
118
|
-
| 9 | data_type_master |
|
|
119
|
-
| 10 | pii_master |
|
|
120
|
-
| 11 | legal_bases_master |
|
|
121
|
-
| 12 | tags |
|
|
122
|
-
| 13 | taggables |
|
|
123
|
-
| 14 | role_master |
|
|
124
|
-
| 15 | rop_type_master |
|
|
125
|
-
| 16 | question_master |
|
|
126
|
-
| 17 | channel_group_master |
|
|
127
|
-
| 18 | dsar_type_master |
|
|
128
|
-
|
|
129
|
-
**เงื่อนไขเพิ่มเติม:**
|
|
130
|
-
|
|
131
|
-
- ตาราง **data_type_master**: ถ้าไม่มีแถวจาก asset ใน target จะ insert ข้อมูลจาก asset ก่อน แล้วใช้ `data_type_id` ที่มีอยู่ทั้งหมดใน target ในการกรอง/อ้างอิง (เพราะมีข้อมูล FK ที่ไม่มีอยู่จริงในระบบ)
|
|
132
|
-
- ตาราง **rop_type_master**: ทำแบบเดียวกัน insert จาก asset ถ้ายังไม่มี, ใช้ `rop_type_id` ใน target ในการกรอง (เพราะมีข้อมูล FK ที่ไม่มีอยู่จริงในระบบ)
|
|
133
|
-
- หลังโอนครบทุกตารางจะมีการ **validate** จำนวนแถว source vs target
|
|
134
|
-
|
|
135
|
-
---
|
|
136
|
-
|
|
137
|
-
### Section 1 (`section-1`) — Core Data
|
|
138
|
-
|
|
139
|
-
**วิธีโอน:** ใช้ `copyDataTables` (โอนตาม PK, รันซ้ำ insert เฉพาะแถวใหม่) + จัดการ `created_by`/`updated_by`
|
|
140
|
-
- **permissions**: โอนจาก source ตามตารางอื่น; การ **เติม/อัปเดต permissions ให้ครบ** ทำแยกด้วย `npm run seed:permissions` (ใช้ข้อมูลจาก `src/assets/data/permissions.ts`)
|
|
141
|
-
|
|
142
|
-
**ตารางที่ insert (ตามลำดับ):**
|
|
143
|
-
|
|
144
|
-
| ลำดับ | ชื่อตาราง |
|
|
145
|
-
|-------|------------|
|
|
146
|
-
| 1 | company_master |
|
|
147
|
-
| 2 | organizations |
|
|
148
|
-
| 3 | systemlangaue |
|
|
149
|
-
| 4 | users |
|
|
150
|
-
| 5 | theme |
|
|
151
|
-
| 6 | roles |
|
|
152
|
-
| 7 | model_has_roles |
|
|
153
|
-
| 8 | permissions |
|
|
154
|
-
| 9 | role_has_permissions |
|
|
155
|
-
| 10 | oauth_clients |
|
|
156
|
-
|
|
157
|
-
**เงื่อนไขเพิ่มเติม:**
|
|
158
|
-
|
|
159
|
-
- **organizations**, **systemlangaue**: อยู่ก่อน `users` จึง insert ด้วย **created_by / updated_by = null** ก่อน แล้วหลัง copy `users` จะ **คืนค่า created_by / updated_by** จาก source ไปอัปเดตใน target (`restoreUserRefsInTable`)
|
|
160
|
-
- **permissions**: รัน `npm run seed:permissions` แยกเพื่อ seed/อัปเดตจาก `src/assets/data/permissions.ts` (unique key `name`; มีใน target แล้วจะ skip)
|
|
161
|
-
- หลังโอนครบจะ **validate** จำนวนแถวของตารางใน section นี้
|
|
162
|
-
|
|
163
|
-
---
|
|
164
|
-
|
|
165
|
-
### Section 2 (`section-2`)
|
|
166
|
-
|
|
167
|
-
**วิธีโอน:** ใช้ `copyDataTables` (รันซ้ำ insert เฉพาะแถวใหม่)
|
|
168
|
-
|
|
169
|
-
**ตารางที่ insert (ตามลำดับ):**
|
|
170
|
-
|
|
171
|
-
| ลำดับ | ชื่อตาราง |
|
|
172
|
-
|-------|------------|
|
|
173
|
-
| 1 | owner_master |
|
|
174
|
-
| 2 | activity_master |
|
|
175
|
-
| 3 | activity_owner_ref_master |
|
|
176
|
-
| 4 | storage_asset_master |
|
|
177
|
-
| 5 | report_preferences |
|
|
178
|
-
| 6 | rop_header |
|
|
179
|
-
| 7 | rop_answer |
|
|
180
|
-
| 8 | rop_gap_results |
|
|
181
|
-
| 9 | rop_activity_advisory_topics |
|
|
182
|
-
| 10 | rop_activity_advisory_comments |
|
|
52
|
+
## API หลัก
|
|
183
53
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
### Section 3 (`section-3`) — Consent
|
|
187
|
-
|
|
188
|
-
**วิธีโอน:** ใช้ `copyDataTables` พร้อม **columnMapping** บางตาราง
|
|
54
|
+
### `copyDataTables(connectionPool, params)`
|
|
189
55
|
|
|
190
|
-
|
|
56
|
+
โอนข้อมูลจาก source ไป target ตาม PK (รันซ้ำจะ insert เฉพาะแถวใหม่)
|
|
191
57
|
|
|
192
|
-
|
|
193
|
-
|-------|------------|
|
|
194
|
-
| 1 | cs_consent_type |
|
|
195
|
-
| 2 | cs_consent_send_template |
|
|
196
|
-
| 3 | thank_consent_msg |
|
|
197
|
-
| 4 | cs_consent_send_template_form |
|
|
198
|
-
| 5 | cs_consent_form_client |
|
|
199
|
-
| 6 | cs_consent_form_result |
|
|
200
|
-
| 7 | cs_consent_form_personal |
|
|
58
|
+
**พารามิเตอร์**
|
|
201
59
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
60
|
+
| พารามิเตอร์ | ประเภท | คำอธิบาย |
|
|
61
|
+
|-------------|--------|----------|
|
|
62
|
+
| `tableNames` | `string[] \| string` | ชื่อตารางที่จะโอน (รองรับ alias `tablesName`) |
|
|
63
|
+
| `options.pageSize` | `number` | จำนวนแถวต่อหน้าการดึงข้อมูล (default: 500) |
|
|
64
|
+
| `options.batchSize` | `number` | จำนวนแถวต่อ batch insert (default: 500) |
|
|
65
|
+
| `setDataOptions` | `SetDataOptions[]` | กำหนดค่าแทนคอลัมน์ก่อน insert |
|
|
66
|
+
| `restoreUserRefsOptions` | `RestoreUserRefsTableOption[]` | ตารางที่ต้องคืนค่า created_by/updated_by หลังโอน |
|
|
67
|
+
| `insteadValueOptions` | `InsteadValueOptions[]` | จัดการ FK ที่ไม่มีในตารางอ้างอิง (ensure row หรือ fallback) |
|
|
68
|
+
| `validateAndUpdate` | `boolean` | `false` = validate เฉพาะอย่างเดียว, `true` = validate แล้วอัปเดตข้อมูลที่ไม่ตรงกัน |
|
|
208
69
|
|
|
209
|
-
|
|
70
|
+
**ผลลัพธ์**
|
|
210
71
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
| 9 | dsar_req_case_del_dtl |
|
|
226
|
-
| 10 | dsar_managements |
|
|
227
|
-
| 11 | dsar_req_case_consent |
|
|
228
|
-
| 12 | dsar_req_case_consent_dtl |
|
|
72
|
+
```ts
|
|
73
|
+
{
|
|
74
|
+
totalRowsTransferred: number;
|
|
75
|
+
tableResults: { tableName: string; rowsTransferred: number }[];
|
|
76
|
+
restoreUserRefsResults: { tableName: string; rowsUpdated: number }[];
|
|
77
|
+
validateResults: {
|
|
78
|
+
tableName: string;
|
|
79
|
+
totalChecked: number;
|
|
80
|
+
mismatchCount: number;
|
|
81
|
+
insertedCount: number;
|
|
82
|
+
updatedCount: number;
|
|
83
|
+
}[];
|
|
84
|
+
}
|
|
85
|
+
```
|
|
229
86
|
|
|
230
87
|
---
|
|
231
88
|
|
|
232
|
-
###
|
|
89
|
+
### `restoreUserRefsInTable(sourcePool, targetPool, tableName, options?)`
|
|
233
90
|
|
|
234
|
-
|
|
91
|
+
คืนค่า `created_by`, `updated_by` ใน target ให้ตรงกับ source (ใช้หลังโอนตารางที่เคย insert ด้วยค่าสองตัวนี้เป็น `null`)
|
|
235
92
|
|
|
236
|
-
|
|
93
|
+
```ts
|
|
94
|
+
import { restoreUserRefsInTable } from "@gumin61/transfer-data-sdk";
|
|
237
95
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
| 3 | incodent_req_log |
|
|
243
|
-
| 4 | incident_estimate |
|
|
244
|
-
| 5 | incident_estimate_log |
|
|
245
|
-
| 6 | incident_agency_personal |
|
|
246
|
-
| 7 | agency_users_pivot |
|
|
247
|
-
| 8 | incident_with_person |
|
|
248
|
-
| 9 | incident_with_person_log |
|
|
96
|
+
await restoreUserRefsInTable(sourcePool, targetPool, "organizations", {
|
|
97
|
+
batchSize: 100,
|
|
98
|
+
});
|
|
99
|
+
```
|
|
249
100
|
|
|
250
101
|
---
|
|
251
102
|
|
|
252
|
-
###
|
|
103
|
+
### `createRestoreUserRefsOptions(tableNames, batchSize?)`
|
|
253
104
|
|
|
254
|
-
|
|
105
|
+
สร้าง `RestoreUserRefsTableOption[]` สำหรับใช้กับ `restoreUserRefsOptions`
|
|
255
106
|
|
|
256
|
-
|
|
107
|
+
```ts
|
|
108
|
+
import { createRestoreUserRefsOptions } from "@gumin61/transfer-data-sdk";
|
|
257
109
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
| 4 | cs_consent_form_content |
|
|
110
|
+
const options = createRestoreUserRefsOptions(
|
|
111
|
+
["organizations"],
|
|
112
|
+
2500
|
|
113
|
+
);
|
|
114
|
+
```
|
|
264
115
|
|
|
265
116
|
---
|
|
266
117
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
**วิธีโอน:** ใช้ `copyTableMaster` (insert เฉพาะแถวที่ PK ยังไม่มีใน target)
|
|
118
|
+
## ตัวอย่างการใช้งานขั้นสูง
|
|
270
119
|
|
|
271
|
-
|
|
120
|
+
### โอนตารางที่มี FK ต้องใส่ null ก่อน
|
|
272
121
|
|
|
273
|
-
|
|
274
|
-
|-------|------------|
|
|
275
|
-
| 1 | ck_type_master |
|
|
276
|
-
| 2 | consent_ck_scan |
|
|
277
|
-
| 3 | consent_ck_scan_dtl |
|
|
278
|
-
| 4 | ck_consent_form |
|
|
279
|
-
| 5 | cs_consent_form_dtl |
|
|
280
|
-
| 6 | ck_ref_master |
|
|
122
|
+
กรณีโอน `organizations` ก่อน `users` → ยังไม่มี user ใน target จึงต้องใส่ `created_by`/`updated_by` เป็น `null` ก่อน แล้วคืนค่าหลังโอน `users` เสร็จ
|
|
281
123
|
|
|
282
|
-
|
|
124
|
+
```ts
|
|
125
|
+
const result = await copyDataTables(
|
|
126
|
+
{ sourcePool, targetPool },
|
|
127
|
+
{
|
|
128
|
+
tableNames: ["organizations", "users"],
|
|
129
|
+
setDataOptions: [
|
|
130
|
+
{ tableName: "organizations", columnName: "created_by", value: null },
|
|
131
|
+
{ tableName: "organizations", columnName: "updated_by", value: null },
|
|
132
|
+
],
|
|
133
|
+
restoreUserRefsOptions: createRestoreUserRefsOptions(
|
|
134
|
+
["organizations"],
|
|
135
|
+
100
|
|
136
|
+
),
|
|
137
|
+
options: { pageSize: 500, batchSize: 500 },
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
```
|
|
283
141
|
|
|
284
|
-
|
|
142
|
+
### จัดการ FK ที่ไม่มีในตารางอ้างอิง
|
|
285
143
|
|
|
286
|
-
|
|
144
|
+
เมื่อ source มี FK ชี้ไปยังแถวที่ไม่มีใน target สามารถกำหนด `insteadValueOptions` ให้:
|
|
145
|
+
- หาแถวในตารางอ้างอิงจาก `lookup` ก่อน
|
|
146
|
+
- ถ้าไม่พบ จะ INSERT `createData` แล้วใช้ `insertId` เป็นค่าของ FK
|
|
287
147
|
|
|
288
|
-
|
|
148
|
+
```ts
|
|
149
|
+
const result = await copyDataTables(
|
|
150
|
+
{ sourcePool, targetPool },
|
|
151
|
+
{
|
|
152
|
+
tableNames: ["pii_master"],
|
|
153
|
+
insteadValueOptions: [
|
|
154
|
+
{
|
|
155
|
+
tableName: "pii_master", // ตารางที่มี FK ที่ไม่มีอยู่จริง(ทำให้เกิดข้อผิดพลาด)
|
|
156
|
+
columnName: "data_type_id", // Column FK ของตาราง
|
|
157
|
+
referenceTableName: "data_type_master", // ตารางที่จะต้องกำหนดข้อมูลใหม่แทนไปก่อน
|
|
158
|
+
referenceColumnName: "data_type_id", // Column PK
|
|
159
|
+
ensureReferenceRow: { // Mock FK Data ขึ้นมา โดย fields จะต้องตรงกับในตารางที่จะ insert
|
|
160
|
+
lookup: { company_id: 1, data_type_name_en: "Mock FK Data" },
|
|
161
|
+
createData: {
|
|
162
|
+
company_id: 1,
|
|
163
|
+
data_type_name_th: "ข้อมูลทดแทน FK",
|
|
164
|
+
data_type_name_en: "Mock FK Data",
|
|
165
|
+
is_deleted: 0,
|
|
166
|
+
created_by: null,
|
|
167
|
+
updated_by: null,
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
options: { pageSize: 500, batchSize: 500 },
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
```
|
|
289
176
|
|
|
290
|
-
|
|
291
|
-
access_master, access_assign_group_user, dsar_type_master, dsar_req_case_del_dtl_log, technical_measures_master, storage_asset_technical_measures, telescope_entries, telescope_entries_tags, cs_consent_timeout, migrations, oauth_refresh_tokens, subscriptions, tbcookielog, failed_jobs, storage_asset_databackup_location, subscribables, user_assign_role, access_assign_user, incident_type_master, notifications, prog_group_master, versions, dsar_incident_doc_status_master, oauth_access_tokens, otp, storage_asset_location_master, user_preference, job_batches, organization_measures_master, dsar_req_case_consent_dtl_log, dsar_req_case_consent_log, incident_req_risk_management, prog_master, new_licenses, group_menu_authority, group_menu_master, chanel_master, risk_master, tbonchangecookielog, dsar_req_case_del_log, tbonfirstactioncookielog, agency_tr_master, source_asset_master, activity_log
|
|
177
|
+
### Validate และอัปเดตข้อมูลที่ไม่ตรงกัน
|
|
292
178
|
|
|
293
|
-
|
|
179
|
+
- `validateAndUpdate: false` — ตรวจสอบและแสดง log เฉพาะอย่างเดียว ไม่แก้ไขข้อมูล
|
|
180
|
+
- `validateAndUpdate: true` — ตรวจสอบแล้ว INSERT/UPDATE ข้อมูลที่ขาดหรือไม่ตรงกันให้ target ตรงกับ source
|
|
294
181
|
|
|
295
|
-
|
|
182
|
+
```ts
|
|
183
|
+
const result = await copyDataTables(
|
|
184
|
+
{ sourcePool, targetPool },
|
|
185
|
+
{
|
|
186
|
+
tableNames: ["users", "permissions"],
|
|
187
|
+
validateAndUpdate: true, // true = validate + update
|
|
188
|
+
options: { pageSize: 500, batchSize: 500 },
|
|
189
|
+
}
|
|
190
|
+
);
|
|
296
191
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
| **section-3** | cs_consent_form_client: columnMapping updated_at ← created_at (จาก source) |
|
|
302
|
-
| **section-6** | cs_consent_form และ cs_consent_form_content ย้ายมาจากรอบ section-3 |
|
|
303
|
-
| **section-7-1** | ใช้ copyTableMaster; ck_ref_master อาจมี FK ที่ไม่มีอยู่จริง |
|
|
304
|
-
| **section-7-2** | ใช้ copyDataTables |
|
|
192
|
+
if (result.validateResults.length > 0) {
|
|
193
|
+
console.table(result.validateResults);
|
|
194
|
+
}
|
|
195
|
+
```
|
|
305
196
|
|
|
306
197
|
---
|
|
307
198
|
|
|
308
|
-
##
|
|
309
|
-
|
|
310
|
-
- **Batch size / Page size**: กำหนดใน `.env` หรือ `src/config/transfer.config.ts` (เช่น `TRANSFER_BATCH_SIZE`, `TRANSFER_PAGE_SIZE`)
|
|
311
|
-
- ตารางที่มีคอลัมน์ LONGTEXT หรือข้อมูลต่อแถวใหญ่ แนะนำให้ลดค่า (เช่น 50–100) เพื่อไม่ให้เกิน `max_allowed_packet` และลดโอกาสข้อมูลผิดพลาด
|
|
312
|
-
- **Database**: กำหนด connection ต้นทางและปลายทางใน `.env` และใช้ใน `src/config/db.source.js` / `src/config/db.target.js`
|
|
313
|
-
- **ลำดับ/รายการตารางต่อ section**: แก้ใน `src/config/sections.config.ts`
|
|
199
|
+
## สรุป Types ที่ Export
|
|
314
200
|
|
|
315
|
-
|
|
201
|
+
```ts
|
|
202
|
+
// ฟังก์ชัน
|
|
203
|
+
copyDataTables(connectionPool, params): Promise<CopyDataTablesResult>
|
|
204
|
+
restoreUserRefsInTable(sourcePool, targetPool, tableName, options?): Promise<{ rowsUpdated: number }>
|
|
205
|
+
createRestoreUserRefsOptions(tableNames, batchSize?): RestoreUserRefsTableOption[]
|
|
206
|
+
|
|
207
|
+
// Types
|
|
208
|
+
ConnectionPool
|
|
209
|
+
CopyDataTablesResult
|
|
210
|
+
TableTransferResult
|
|
211
|
+
RestoreUserRefsResult
|
|
212
|
+
RestoreUserRefsTableOption
|
|
213
|
+
ValidateTableResult
|
|
214
|
+
SetDataOptions
|
|
215
|
+
InsteadValueOptions
|
|
216
|
+
TransferOptions
|
|
217
|
+
```
|
|
316
218
|
|
|
317
|
-
|
|
219
|
+
---
|