@simplysm/sd-cli 10.0.22 → 10.0.23

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.
Files changed (239) hide show
  1. package/dist/SdTsIncrementalBuilder.d.ts +1 -1
  2. package/dist/SdTsIncrementalBuilder.js.map +1 -1
  3. package/dist/SdTsIncrementalBuilder.mjs +39 -16
  4. package/package.json +4 -4
  5. package/src/SdTsIncrementalBuilder.ts +29 -4
  6. package/dist/sd-core-common/src/decorators/NotifyPropertyChange.d.ts +0 -20
  7. package/dist/sd-core-common/src/decorators/NotifyPropertyChange.js.map +0 -1
  8. package/dist/sd-core-common/src/decorators/NotifyPropertyChange.mjs +0 -12
  9. package/dist/sd-core-common/src/decorators/PropertyGetSetDecoratorBase.d.ts +0 -43
  10. package/dist/sd-core-common/src/decorators/PropertyGetSetDecoratorBase.js.map +0 -1
  11. package/dist/sd-core-common/src/decorators/PropertyGetSetDecoratorBase.mjs +0 -54
  12. package/dist/sd-core-common/src/decorators/PropertyValidate.d.ts +0 -16
  13. package/dist/sd-core-common/src/decorators/PropertyValidate.js.map +0 -1
  14. package/dist/sd-core-common/src/decorators/PropertyValidate.mjs +0 -26
  15. package/dist/sd-core-common/src/decorators/decorator-return-types.d.ts +0 -14
  16. package/dist/sd-core-common/src/decorators/decorator-return-types.js.map +0 -1
  17. package/dist/sd-core-common/src/decorators/decorator-return-types.mjs +0 -2
  18. package/dist/sd-core-common/src/errors/ArgumentError.d.ts +0 -10
  19. package/dist/sd-core-common/src/errors/ArgumentError.js.map +0 -1
  20. package/dist/sd-core-common/src/errors/ArgumentError.mjs +0 -13
  21. package/dist/sd-core-common/src/errors/NeverEntryError.d.ts +0 -10
  22. package/dist/sd-core-common/src/errors/NeverEntryError.js.map +0 -1
  23. package/dist/sd-core-common/src/errors/NeverEntryError.mjs +0 -13
  24. package/dist/sd-core-common/src/errors/NotImplementError.d.ts +0 -10
  25. package/dist/sd-core-common/src/errors/NotImplementError.js.map +0 -1
  26. package/dist/sd-core-common/src/errors/NotImplementError.mjs +0 -13
  27. package/dist/sd-core-common/src/errors/SdError.d.ts +0 -23
  28. package/dist/sd-core-common/src/errors/SdError.js.map +0 -1
  29. package/dist/sd-core-common/src/errors/SdError.mjs +0 -40
  30. package/dist/sd-core-common/src/errors/TimeoutError.d.ts +0 -11
  31. package/dist/sd-core-common/src/errors/TimeoutError.js.map +0 -1
  32. package/dist/sd-core-common/src/errors/TimeoutError.mjs +0 -16
  33. package/dist/sd-core-common/src/extensions/ArrayExtension.d.ts +0 -147
  34. package/dist/sd-core-common/src/extensions/ArrayExtension.js.map +0 -1
  35. package/dist/sd-core-common/src/extensions/ArrayExtension.mjs +0 -448
  36. package/dist/sd-core-common/src/extensions/MapExtension.d.ts +0 -4
  37. package/dist/sd-core-common/src/extensions/MapExtension.js.map +0 -1
  38. package/dist/sd-core-common/src/extensions/MapExtension.mjs +0 -15
  39. package/dist/sd-core-common/src/extensions/SetExtension.d.ts +0 -3
  40. package/dist/sd-core-common/src/extensions/SetExtension.js.map +0 -1
  41. package/dist/sd-core-common/src/extensions/SetExtension.mjs +0 -10
  42. package/dist/sd-core-common/src/index.d.ts +0 -32
  43. package/dist/sd-core-common/src/index.js.map +0 -1
  44. package/dist/sd-core-common/src/index.mjs +0 -33
  45. package/dist/sd-core-common/src/types/DateOnly.d.ts +0 -135
  46. package/dist/sd-core-common/src/types/DateOnly.js.map +0 -1
  47. package/dist/sd-core-common/src/types/DateOnly.mjs +0 -220
  48. package/dist/sd-core-common/src/types/DateTime.d.ts +0 -42
  49. package/dist/sd-core-common/src/types/DateTime.js.map +0 -1
  50. package/dist/sd-core-common/src/types/DateTime.mjs +0 -156
  51. package/dist/sd-core-common/src/types/DeepPartial.d.ts +0 -3
  52. package/dist/sd-core-common/src/types/DeepPartial.js.map +0 -1
  53. package/dist/sd-core-common/src/types/DeepPartial.mjs +0 -2
  54. package/dist/sd-core-common/src/types/ObjectSet.d.ts +0 -4
  55. package/dist/sd-core-common/src/types/ObjectSet.js.map +0 -1
  56. package/dist/sd-core-common/src/types/ObjectSet.mjs +0 -18
  57. package/dist/sd-core-common/src/types/Time.d.ts +0 -27
  58. package/dist/sd-core-common/src/types/Time.js.map +0 -1
  59. package/dist/sd-core-common/src/types/Time.mjs +0 -108
  60. package/dist/sd-core-common/src/types/Type.d.ts +0 -7
  61. package/dist/sd-core-common/src/types/Type.js.map +0 -1
  62. package/dist/sd-core-common/src/types/Type.mjs +0 -2
  63. package/dist/sd-core-common/src/types/UnwrappedType.d.ts +0 -1
  64. package/dist/sd-core-common/src/types/UnwrappedType.js.map +0 -1
  65. package/dist/sd-core-common/src/types/UnwrappedType.mjs +0 -2
  66. package/dist/sd-core-common/src/types/Uuid.d.ts +0 -8
  67. package/dist/sd-core-common/src/types/Uuid.js.map +0 -1
  68. package/dist/sd-core-common/src/types/Uuid.mjs +0 -26
  69. package/dist/sd-core-common/src/types/WrappedType.d.ts +0 -1
  70. package/dist/sd-core-common/src/types/WrappedType.js.map +0 -1
  71. package/dist/sd-core-common/src/types/WrappedType.mjs +0 -2
  72. package/dist/sd-core-common/src/utils/DateTimeFormatUtil.d.ts +0 -12
  73. package/dist/sd-core-common/src/utils/DateTimeFormatUtil.js.map +0 -1
  74. package/dist/sd-core-common/src/utils/DateTimeFormatUtil.mjs +0 -67
  75. package/dist/sd-core-common/src/utils/FunctionQueue.d.ts +0 -8
  76. package/dist/sd-core-common/src/utils/FunctionQueue.js.map +0 -1
  77. package/dist/sd-core-common/src/utils/FunctionQueue.mjs +0 -46
  78. package/dist/sd-core-common/src/utils/FunctionUtil.d.ts +0 -6
  79. package/dist/sd-core-common/src/utils/FunctionUtil.js.map +0 -1
  80. package/dist/sd-core-common/src/utils/FunctionUtil.mjs +0 -31
  81. package/dist/sd-core-common/src/utils/JsonConvert.d.ts +0 -8
  82. package/dist/sd-core-common/src/utils/JsonConvert.js.map +0 -1
  83. package/dist/sd-core-common/src/utils/JsonConvert.mjs +0 -78
  84. package/dist/sd-core-common/src/utils/MathUtil.d.ts +0 -3
  85. package/dist/sd-core-common/src/utils/MathUtil.js.map +0 -1
  86. package/dist/sd-core-common/src/utils/MathUtil.mjs +0 -6
  87. package/dist/sd-core-common/src/utils/NumberUtil.d.ts +0 -6
  88. package/dist/sd-core-common/src/utils/NumberUtil.js.map +0 -1
  89. package/dist/sd-core-common/src/utils/NumberUtil.mjs +0 -32
  90. package/dist/sd-core-common/src/utils/ObjectUtil.d.ts +0 -80
  91. package/dist/sd-core-common/src/utils/ObjectUtil.js.map +0 -1
  92. package/dist/sd-core-common/src/utils/ObjectUtil.mjs +0 -452
  93. package/dist/sd-core-common/src/utils/SdSyncEventEmitter.d.ts +0 -6
  94. package/dist/sd-core-common/src/utils/SdSyncEventEmitter.js.map +0 -1
  95. package/dist/sd-core-common/src/utils/SdSyncEventEmitter.mjs +0 -27
  96. package/dist/sd-core-common/src/utils/StringUtil.d.ts +0 -8
  97. package/dist/sd-core-common/src/utils/StringUtil.js.map +0 -1
  98. package/dist/sd-core-common/src/utils/StringUtil.mjs +0 -77
  99. package/dist/sd-core-common/src/utils/Wait.d.ts +0 -4
  100. package/dist/sd-core-common/src/utils/Wait.js.map +0 -1
  101. package/dist/sd-core-common/src/utils/Wait.mjs +0 -23
  102. package/dist/sd-core-node/src/index.d.ts +0 -6
  103. package/dist/sd-core-node/src/index.js.map +0 -1
  104. package/dist/sd-core-node/src/index.mjs +0 -7
  105. package/dist/sd-core-node/src/utils/FsUtil.d.ts +0 -44
  106. package/dist/sd-core-node/src/utils/FsUtil.js.map +0 -1
  107. package/dist/sd-core-node/src/utils/FsUtil.mjs +0 -493
  108. package/dist/sd-core-node/src/utils/Logger.d.ts +0 -91
  109. package/dist/sd-core-node/src/utils/Logger.js.map +0 -1
  110. package/dist/sd-core-node/src/utils/Logger.mjs +0 -185
  111. package/dist/sd-core-node/src/utils/PathUtil.d.ts +0 -6
  112. package/dist/sd-core-node/src/utils/PathUtil.js.map +0 -1
  113. package/dist/sd-core-node/src/utils/PathUtil.mjs +0 -24
  114. package/dist/sd-core-node/src/utils/SdFsWatcher.d.ts +0 -15
  115. package/dist/sd-core-node/src/utils/SdFsWatcher.js.map +0 -1
  116. package/dist/sd-core-node/src/utils/SdFsWatcher.mjs +0 -43
  117. package/dist/sd-core-node/src/utils/SdProcess.d.ts +0 -5
  118. package/dist/sd-core-node/src/utils/SdProcess.js.map +0 -1
  119. package/dist/sd-core-node/src/utils/SdProcess.mjs +0 -36
  120. package/dist/sd-orm-common/src/CaseQueryHelper.d.ts +0 -12
  121. package/dist/sd-orm-common/src/CaseQueryHelper.js.map +0 -1
  122. package/dist/sd-orm-common/src/CaseQueryHelper.mjs +0 -19
  123. package/dist/sd-orm-common/src/CaseWhenQueryHelper.d.ts +0 -12
  124. package/dist/sd-orm-common/src/CaseWhenQueryHelper.js.map +0 -1
  125. package/dist/sd-orm-common/src/CaseWhenQueryHelper.mjs +0 -20
  126. package/dist/sd-orm-common/src/DbContext.d.ts +0 -81
  127. package/dist/sd-orm-common/src/DbContext.js.map +0 -1
  128. package/dist/sd-orm-common/src/DbContext.mjs +0 -635
  129. package/dist/sd-orm-common/src/IDbConnection.d.ts +0 -15
  130. package/dist/sd-orm-common/src/IDbConnection.js.map +0 -1
  131. package/dist/sd-orm-common/src/IDbConnection.mjs +0 -2
  132. package/dist/sd-orm-common/src/IDbContextExecutor.d.ts +0 -17
  133. package/dist/sd-orm-common/src/IDbContextExecutor.js.map +0 -1
  134. package/dist/sd-orm-common/src/IDbContextExecutor.mjs +0 -2
  135. package/dist/sd-orm-common/src/IDbMigration.d.ts +0 -4
  136. package/dist/sd-orm-common/src/IDbMigration.js.map +0 -1
  137. package/dist/sd-orm-common/src/IDbMigration.mjs +0 -2
  138. package/dist/sd-orm-common/src/QueryBuilder.d.ts +0 -48
  139. package/dist/sd-orm-common/src/QueryBuilder.js.map +0 -1
  140. package/dist/sd-orm-common/src/QueryBuilder.mjs +0 -1022
  141. package/dist/sd-orm-common/src/QueryHelper.d.ts +0 -75
  142. package/dist/sd-orm-common/src/QueryHelper.js.map +0 -1
  143. package/dist/sd-orm-common/src/QueryHelper.mjs +0 -627
  144. package/dist/sd-orm-common/src/QueryUnit.d.ts +0 -10
  145. package/dist/sd-orm-common/src/QueryUnit.js.map +0 -1
  146. package/dist/sd-orm-common/src/QueryUnit.mjs +0 -16
  147. package/dist/sd-orm-common/src/Queryable.d.ts +0 -105
  148. package/dist/sd-orm-common/src/Queryable.js.map +0 -1
  149. package/dist/sd-orm-common/src/Queryable.mjs +0 -1375
  150. package/dist/sd-orm-common/src/SdOrmDataType.d.ts +0 -21
  151. package/dist/sd-orm-common/src/SdOrmDataType.js.map +0 -1
  152. package/dist/sd-orm-common/src/SdOrmDataType.mjs +0 -2
  153. package/dist/sd-orm-common/src/commons.d.ts +0 -400
  154. package/dist/sd-orm-common/src/commons.js.map +0 -1
  155. package/dist/sd-orm-common/src/commons.mjs +0 -8
  156. package/dist/sd-orm-common/src/decorators.d.ts +0 -29
  157. package/dist/sd-orm-common/src/decorators.js.map +0 -1
  158. package/dist/sd-orm-common/src/decorators.mjs +0 -89
  159. package/dist/sd-orm-common/src/index.d.ts +0 -17
  160. package/dist/sd-orm-common/src/index.js.map +0 -1
  161. package/dist/sd-orm-common/src/index.mjs +0 -18
  162. package/dist/sd-orm-common/src/models/SystemMigration.d.ts +0 -3
  163. package/dist/sd-orm-common/src/models/SystemMigration.js.map +0 -1
  164. package/dist/sd-orm-common/src/models/SystemMigration.mjs +0 -13
  165. package/dist/sd-orm-common/src/utils/DbDefinitionUtil.d.ts +0 -14
  166. package/dist/sd-orm-common/src/utils/DbDefinitionUtil.js.map +0 -1
  167. package/dist/sd-orm-common/src/utils/DbDefinitionUtil.mjs +0 -66
  168. package/dist/sd-orm-common/src/utils/SdOrmUtil.d.ts +0 -8
  169. package/dist/sd-orm-common/src/utils/SdOrmUtil.js.map +0 -1
  170. package/dist/sd-orm-common/src/utils/SdOrmUtil.mjs +0 -248
  171. package/dist/sd-orm-node/src/DbConnectionFactory.d.ts +0 -4
  172. package/dist/sd-orm-node/src/DbConnectionFactory.js.map +0 -1
  173. package/dist/sd-orm-node/src/DbConnectionFactory.mjs +0 -17
  174. package/dist/sd-orm-node/src/NodeDbContextExecutor.d.ts +0 -19
  175. package/dist/sd-orm-node/src/NodeDbContextExecutor.js.map +0 -1
  176. package/dist/sd-orm-node/src/NodeDbContextExecutor.mjs +0 -71
  177. package/dist/sd-orm-node/src/SdOrm.d.ts +0 -10
  178. package/dist/sd-orm-node/src/SdOrm.js.map +0 -1
  179. package/dist/sd-orm-node/src/SdOrm.mjs +0 -25
  180. package/dist/sd-orm-node/src/index.d.ts +0 -4
  181. package/dist/sd-orm-node/src/index.js.map +0 -1
  182. package/dist/sd-orm-node/src/index.mjs +0 -5
  183. package/dist/sd-orm-node-mssql/src/MssqlDbConnection.d.ts +0 -25
  184. package/dist/sd-orm-node-mssql/src/MssqlDbConnection.js.map +0 -1
  185. package/dist/sd-orm-node-mssql/src/MssqlDbConnection.mjs +0 -321
  186. package/dist/sd-orm-node-mssql/src/index.d.ts +0 -2
  187. package/dist/sd-orm-node-mssql/src/index.js.map +0 -1
  188. package/dist/sd-orm-node-mssql/src/index.mjs +0 -3
  189. package/dist/sd-orm-node-mysql/src/MysqlDbConnection.d.ts +0 -22
  190. package/dist/sd-orm-node-mysql/src/MysqlDbConnection.js.map +0 -1
  191. package/dist/sd-orm-node-mysql/src/MysqlDbConnection.mjs +0 -200
  192. package/dist/sd-orm-node-mysql/src/index.d.ts +0 -2
  193. package/dist/sd-orm-node-mysql/src/index.js.map +0 -1
  194. package/dist/sd-orm-node-mysql/src/index.mjs +0 -3
  195. package/dist/sd-orm-node-sqlite/src/SqliteDbConnection.d.ts +0 -22
  196. package/dist/sd-orm-node-sqlite/src/SqliteDbConnection.js.map +0 -1
  197. package/dist/sd-orm-node-sqlite/src/SqliteDbConnection.mjs +0 -172
  198. package/dist/sd-orm-node-sqlite/src/index.d.ts +0 -2
  199. package/dist/sd-orm-node-sqlite/src/index.js.map +0 -1
  200. package/dist/sd-orm-node-sqlite/src/index.mjs +0 -3
  201. package/dist/sd-service-common/src/commons-orm.d.ts +0 -4
  202. package/dist/sd-service-common/src/commons-orm.js.map +0 -1
  203. package/dist/sd-service-common/src/commons-orm.mjs +0 -2
  204. package/dist/sd-service-common/src/commons-smtp.d.ts +0 -29
  205. package/dist/sd-service-common/src/commons-smtp.js.map +0 -1
  206. package/dist/sd-service-common/src/commons-smtp.mjs +0 -2
  207. package/dist/sd-service-common/src/commons.d.ts +0 -57
  208. package/dist/sd-service-common/src/commons.js.map +0 -1
  209. package/dist/sd-service-common/src/commons.mjs +0 -3
  210. package/dist/sd-service-common/src/index.d.ts +0 -3
  211. package/dist/sd-service-common/src/index.js.map +0 -1
  212. package/dist/sd-service-common/src/index.mjs +0 -4
  213. package/dist/sd-service-server/src/ApiServiceError.d.ts +0 -12
  214. package/dist/sd-service-server/src/ApiServiceError.js.map +0 -1
  215. package/dist/sd-service-server/src/ApiServiceError.mjs +0 -15
  216. package/dist/sd-service-server/src/SdServiceServer.d.ts +0 -39
  217. package/dist/sd-service-server/src/SdServiceServer.js.map +0 -1
  218. package/dist/sd-service-server/src/SdServiceServer.mjs +0 -513
  219. package/dist/sd-service-server/src/commons.d.ts +0 -23
  220. package/dist/sd-service-server/src/commons.js.map +0 -1
  221. package/dist/sd-service-server/src/commons.mjs +0 -3
  222. package/dist/sd-service-server/src/index.d.ts +0 -8
  223. package/dist/sd-service-server/src/index.js.map +0 -1
  224. package/dist/sd-service-server/src/index.mjs +0 -9
  225. package/dist/sd-service-server/src/services/SdAutoUpdateService.d.ts +0 -4
  226. package/dist/sd-service-server/src/services/SdAutoUpdateService.js.map +0 -1
  227. package/dist/sd-service-server/src/services/SdAutoUpdateService.mjs +0 -20
  228. package/dist/sd-service-server/src/services/SdCryptoService.d.ts +0 -7
  229. package/dist/sd-service-server/src/services/SdCryptoService.js.map +0 -1
  230. package/dist/sd-service-server/src/services/SdCryptoService.mjs +0 -39
  231. package/dist/sd-service-server/src/services/SdOrmService.d.ts +0 -22
  232. package/dist/sd-service-server/src/services/SdOrmService.js.map +0 -1
  233. package/dist/sd-service-server/src/services/SdOrmService.mjs +0 -115
  234. package/dist/sd-service-server/src/services/SdSmtpClientService.d.ts +0 -6
  235. package/dist/sd-service-server/src/services/SdSmtpClientService.js.map +0 -1
  236. package/dist/sd-service-server/src/services/SdSmtpClientService.mjs +0 -44
  237. package/dist/sd-service-server/src/utils/SdServiceServerConfigUtil.d.ts +0 -4
  238. package/dist/sd-service-server/src/utils/SdServiceServerConfigUtil.js.map +0 -1
  239. package/dist/sd-service-server/src/utils/SdServiceServerConfigUtil.mjs +0 -36
@@ -1,1375 +0,0 @@
1
- import { FunctionUtil, NeverEntryError, ObjectUtil } from "@simplysm/sd-core-common";
2
- import { DbDefinitionUtil } from "./utils/DbDefinitionUtil";
3
- import { QueryUnit } from "./QueryUnit";
4
- import { SdOrmUtil } from "./utils/SdOrmUtil";
5
- export class Queryable {
6
- get tableName() {
7
- if (!this.tableDef)
8
- throw new NeverEntryError();
9
- return this.db.qb.getTableName(this.tableNameDef);
10
- }
11
- get tableDescription() {
12
- if (!this.tableDef)
13
- throw new NeverEntryError();
14
- return this.tableDef.description;
15
- }
16
- get tableNameDef() {
17
- if (!this.tableDef)
18
- throw new NeverEntryError();
19
- return {
20
- ...this.db.opt.dialect === "sqlite" ? {} : {
21
- database: this.tableDef.database ?? this.db.opt.database,
22
- schema: this.tableDef.schema ?? this.db.opt.schema
23
- },
24
- name: this.tableDef.name
25
- };
26
- }
27
- constructor(db, arg1, arg2, arg3, arg4) {
28
- this.db = db;
29
- this._isCustomEntity = false;
30
- this.hasMultiJoin = false;
31
- // Clone 일때
32
- if (arg1 instanceof Queryable) {
33
- this.tableType = arg1.tableType;
34
- this._as = arg1._as;
35
- this.tableDef = arg1.tableDef ? ObjectUtil.clone(arg1.tableDef) : undefined;
36
- this._entity = ObjectUtil.clone(arg1._entity);
37
- this._def = ObjectUtil.clone(arg1._def);
38
- if (arg2 !== undefined) {
39
- this._entity = ObjectUtil.clone(arg2, {
40
- useRefTypes: [this.db.constructor]
41
- });
42
- this._isCustomEntity = true;
43
- }
44
- }
45
- // 일반 생성
46
- else if (arg3 === undefined) {
47
- this.tableType = arg1;
48
- this._as = arg2;
49
- // Init TABLE Definition
50
- const tableDef = DbDefinitionUtil.getTableDef(this.tableType);
51
- if (typeof tableDef === "undefined") {
52
- throw new Error(`'${this.tableType.name}'에 '@Table()'이 지정되지 않았습니다.`);
53
- }
54
- this.tableDef = tableDef;
55
- // Init Entity
56
- this._entity = {};
57
- for (const colDef of this.tableDef.columns) {
58
- this._entity[colDef.propertyKey] = new QueryUnit(colDef.typeFwd(), `${this.db.qb.wrap(`TBL${this._as !== undefined ? `.${this._as}` : ""}`)}.${this.db.qb.wrap(colDef.name)}`);
59
- }
60
- // Init FROM
61
- this._def = {
62
- from: this.tableName
63
- };
64
- }
65
- // tableDef 없이 생성 (wrapping)
66
- else {
67
- this._as = arg2;
68
- this._entity = arg3;
69
- this._def = arg4;
70
- if (arg1 !== undefined) {
71
- this.tableType = arg1;
72
- // Init TABLE Definition
73
- const tableDef = DbDefinitionUtil.getTableDef(this.tableType);
74
- if (typeof tableDef === "undefined") {
75
- throw new Error(`'${this.tableType.name}'에 '@Table()'이 지정되지 않았습니다.`);
76
- }
77
- this.tableDef = tableDef;
78
- }
79
- }
80
- }
81
- static union(qrs, as) {
82
- const db = qrs[0].db;
83
- const cqrs = qrs.map((item) => new Queryable(db, item).wrap().clearOrderBy());
84
- const getNewEntity = (orgEntity) => {
85
- const resultEntity = {};
86
- for (const orgEntityKey of Object.keys(orgEntity)) {
87
- const orgEntityValue = orgEntity[orgEntityKey];
88
- if (SdOrmUtil.canConvertToQueryValue(orgEntityValue)) {
89
- resultEntity[orgEntityKey] = new QueryUnit(SdOrmUtil.getQueryValueType(orgEntityValue), `${cqrs[0].db.qb.wrap(`TBL${as !== undefined ? "." + as : ""}`)}.${cqrs[0].db.qb.wrap(orgEntityKey)}`);
90
- }
91
- else if (orgEntityValue instanceof Array) {
92
- resultEntity[orgEntityKey] = [getNewEntity(orgEntityValue[0])];
93
- }
94
- else {
95
- resultEntity[orgEntityKey] = getNewEntity(orgEntityValue);
96
- }
97
- }
98
- return resultEntity;
99
- };
100
- const entity = getNewEntity(cqrs[0]._entity);
101
- // Init entity
102
- /*const entity = {} as TEntity<NT>;
103
- for (const entityKey of Object.keys(cqrs[0]._entity)) {
104
- const entityValue = cqrs[0]._entity[entityKey];
105
- if (SdOrmUtil.canConvertToQueryValue(entityValue)) {
106
- entity[entityKey] = new QueryUnit(SdOrmUtil.getQueryValueType(entityValue), `${cqrs[0].db.qb.wrap(`TBL${as !== undefined ? "." + as : ""}`)}.${cqrs[0].db.qb.wrap(entityKey)}`);
107
- }
108
- else {
109
-
110
- }
111
- /!*if (!SdOrmUtil.canConvertToQueryValue(entityValue)) {
112
- throw new Error("단일계층 이상의 구조를 가진 'queryable' 은 UNION 할 수 없습니다. select 를 통해 단일계층으로 만드세요.");
113
- }
114
-
115
- entity[entityKey] = new QueryUnit(SdOrmUtil.getQueryValueType(entityValue), `${cqrs[0].db.qb.wrap(`TBL${as !== undefined ? "." + as : ""}`)}.${cqrs[0].db.qb.wrap(entityKey)}`);*!/
116
- }*/
117
- // Init defs.from
118
- const from = cqrs.map((item) => item.getSelectQueryDef());
119
- return new Queryable(db, undefined, as, entity, { from });
120
- }
121
- lock() {
122
- const result = new Queryable(this.db, this);
123
- result._def.lock = true;
124
- return result;
125
- }
126
- select(fwd) {
127
- const newEntity = fwd(this._entity);
128
- return new Queryable(this.db, this, newEntity);
129
- }
130
- selectByType(tableType) {
131
- const tableDef = DbDefinitionUtil.getTableDef(tableType);
132
- if (typeof tableDef === "undefined") {
133
- throw new Error(`'${tableType.name}'에 '@Table()'이 지정되지 않았습니다.`);
134
- }
135
- const newEntity = {};
136
- for (const colDef of tableDef.columns) {
137
- newEntity[colDef.propertyKey] = this._entity[colDef.propertyKey];
138
- }
139
- return new Queryable(this.db, this, newEntity);
140
- }
141
- ofType() {
142
- return this;
143
- }
144
- where(predicate) {
145
- const result = new Queryable(this.db, this);
146
- const where = this.db.qh.and(predicate(this._entity));
147
- result._def.where = result._def.where ? this.db.qh.and([result._def.where, where]) : where;
148
- return result;
149
- }
150
- distinct() {
151
- const result = new Queryable(this.db, this);
152
- result._def.distinct = true;
153
- return result;
154
- }
155
- top(count) {
156
- const result = new Queryable(this.db, this);
157
- result._def.top = count;
158
- return result;
159
- }
160
- orderBy(arg1, desc) {
161
- let result = new Queryable(this.db, this);
162
- let selectedColumn;
163
- if (typeof arg1 === "function") {
164
- selectedColumn = arg1(this._entity);
165
- }
166
- else /*if (typeof arg1 === "string")*/ {
167
- const chain = arg1.split(".").slice(0, -1);
168
- const asChainArr = [];
169
- for (const fkName of chain) {
170
- asChainArr.push(fkName);
171
- const as = asChainArr.join(".");
172
- if (!this._def.join?.some((item) => item.as === this.db.qb.wrap(`TBL.${as}`))) {
173
- if (this._getEntityChainValue(result._entity, as) === undefined) {
174
- result = result.includeByTableChainedName(as);
175
- }
176
- }
177
- }
178
- selectedColumn = this._getEntityChainValue(result._entity, arg1);
179
- }
180
- /*else {
181
- for (const orderingItem of arg1) {
182
- result = result.orderBy(orderingItem.key, orderingItem.desc);
183
- }
184
- return result;
185
- }*/
186
- result._def.orderBy = result._def.orderBy ?? [];
187
- const queryValue = this.db.qh.getQueryValue(selectedColumn);
188
- if (result._def.orderBy.some((item) => item[0] === queryValue)) {
189
- throw new Error("정렬 기준이 중복 되었습니다: " + queryValue);
190
- }
191
- result._def.orderBy.push([queryValue, (desc ? "DESC" : "ASC")]);
192
- return result;
193
- }
194
- clearOrderBy() {
195
- const result = new Queryable(this.db, this);
196
- delete result._def.orderBy;
197
- return result;
198
- }
199
- limit(skip, take) {
200
- const result = new Queryable(this.db, this);
201
- result._def.limit = [skip, take];
202
- return result;
203
- }
204
- sample(rowCount) {
205
- const result = new Queryable(this.db, this);
206
- result._def.sample = rowCount;
207
- return result;
208
- }
209
- pivot(valueFwd, valueDupFwd, emptyValue, pivotFwd, pivotKeys) {
210
- const valueColumn = valueFwd(this._entity);
211
- const pivotColumn = pivotFwd(this._entity);
212
- const entity = { ...this._entity };
213
- if (this.db.opt.dialect === "mysql") {
214
- for (const pivotKey of pivotKeys) {
215
- if (valueColumn instanceof QueryUnit) {
216
- // const asWrap = this.db.qb.wrap(`TBL${this._as !== undefined ? `.${this._as}` : ""}`);
217
- entity[pivotKey] = valueDupFwd(new QueryUnit(valueColumn.type, [`IF(`, this.db.qh.getQueryValue(pivotColumn), ` = '${pivotKey}', `, this.db.qh.getQueryValue(valueColumn), ", ", this.db.qh.getQueryValue(emptyValue), `)`]));
218
- }
219
- else {
220
- throw new Error("미구현");
221
- }
222
- }
223
- }
224
- else {
225
- for (const pivotKey of pivotKeys) {
226
- if (valueColumn instanceof QueryUnit) {
227
- entity[pivotKey] = new QueryUnit(valueColumn.type, `${this.db.qb.wrap(`TBL${this._as !== undefined ? `.${this._as}` : ""}`)}.${this.db.qb.wrap(pivotKey)}`);
228
- }
229
- else {
230
- throw new Error("미구현");
231
- }
232
- }
233
- }
234
- let result = new Queryable(this.db, this, entity);
235
- if (this.db.opt.dialect === "mysql") {
236
- result = result
237
- .groupBy((item) => Object.entries(item)
238
- .filter(([k, v]) => (!pivotKeys.includes(k)
239
- && !ObjectUtil.equal(v, valueColumn)
240
- && !ObjectUtil.equal(v, pivotColumn)))
241
- .map(([k, v]) => v));
242
- }
243
- else {
244
- result._def.pivot = {
245
- valueColumn: this.db.qh.getQueryValue(valueDupFwd(valueColumn)),
246
- pivotColumn: this.db.qh.getQueryValue(pivotColumn),
247
- pivotKeys
248
- };
249
- }
250
- return result;
251
- }
252
- unpivot(valueColumn, pivotColumn, pivotKeys, resultType) {
253
- const entity = { ...this._entity };
254
- if (this.db.opt.dialect === "mysql") {
255
- throw new Error("MYSQL 미구현");
256
- }
257
- else {
258
- if (entity[pivotKeys[0]] instanceof QueryUnit) {
259
- entity[valueColumn] = new QueryUnit(entity[pivotKeys[0]].type, `${this.db.qb.wrap(`TBL${this._as !== undefined ? `.${this._as}` : ""}`)}.${this.db.qb.wrap(valueColumn)}`);
260
- entity[pivotColumn] = new QueryUnit(String, `${this.db.qb.wrap(`TBL${this._as !== undefined ? `.${this._as}` : ""}`)}.${this.db.qb.wrap(pivotColumn)}`);
261
- for (const pivotKey of pivotKeys) {
262
- delete entity[pivotKey];
263
- }
264
- }
265
- else {
266
- throw new Error("미구현");
267
- }
268
- }
269
- const result = new Queryable(this.db, this, entity);
270
- result._def.unpivot = {
271
- valueColumn: this.db.qb.wrap(valueColumn),
272
- pivotColumn: this.db.qb.wrap(pivotColumn),
273
- pivotKeys
274
- };
275
- return result;
276
- }
277
- groupBy(fwd) {
278
- const result = new Queryable(this.db, this);
279
- result._def.groupBy = fwd(this._entity).map((item) => this.db.qh.getQueryValue(item))
280
- .filter((item) => item !== "NULL");
281
- return result;
282
- }
283
- having(predicate) {
284
- const result = new Queryable(this.db, this);
285
- const having = this.db.qh.and(predicate(this._entity));
286
- result._def.having = result._def.having ? this.db.qh.and([result._def.having, having]) : having;
287
- return result;
288
- }
289
- join(joinTypeOrQrs, as, fwd) {
290
- const realAs = this._as !== undefined ? this._as + "." + as : as;
291
- if (this._def.join?.some((item) => item.as === this.db.qb.wrap(`TBL.${realAs}`))) {
292
- return new Queryable(this.db, this);
293
- }
294
- let joinTableQueryable;
295
- if (joinTypeOrQrs instanceof Array) {
296
- joinTableQueryable = Queryable.union(joinTypeOrQrs, realAs);
297
- }
298
- else {
299
- joinTableQueryable = new Queryable(this.db, joinTypeOrQrs, realAs);
300
- }
301
- const joinQueryable = fwd(joinTableQueryable, this._entity);
302
- const joinEntity = this._getParentEntity(joinQueryable._entity, realAs, undefined);
303
- const entity = { ...this._entity };
304
- this._setEntityChainValue(entity, as, [joinEntity]);
305
- const result = new Queryable(this.db, this, entity);
306
- result._def.join = result._def.join ?? [];
307
- result._def.join.push({
308
- ...joinQueryable.getSelectQueryDef(),
309
- isCustomSelect: joinQueryable._isCustomEntity,
310
- isSingle: false
311
- });
312
- this.hasMultiJoin = true;
313
- return result;
314
- }
315
- joinSingle(joinTypeOrQrs, as, fwd) {
316
- const realAs = this._as !== undefined ? this._as + "." + as : as;
317
- if (this._def.join?.some((item) => item.as === this.db.qb.wrap(`TBL.${realAs}`))) {
318
- return new Queryable(this.db, this);
319
- }
320
- let joinTableQueryable;
321
- if (joinTypeOrQrs instanceof Array) {
322
- joinTableQueryable = Queryable.union(joinTypeOrQrs, realAs);
323
- }
324
- else {
325
- joinTableQueryable = new Queryable(this.db, joinTypeOrQrs, realAs);
326
- }
327
- const joinQueryable = fwd(joinTableQueryable, this._entity);
328
- const joinEntity = this._getParentEntity(joinQueryable._entity, realAs, undefined);
329
- const entity = { ...this._entity };
330
- this._setEntityChainValue(entity, as, joinEntity);
331
- const result = new Queryable(this.db, this, entity);
332
- result._def.join = result._def.join ?? [];
333
- result._def.join.push({
334
- ...joinQueryable.getSelectQueryDef(),
335
- isCustomSelect: joinQueryable._isCustomEntity,
336
- isSingle: true
337
- });
338
- this.hasMultiJoin = this.hasMultiJoin || joinQueryable.hasMultiJoin;
339
- return result;
340
- }
341
- includeByTableChainedName(tableChainedName) {
342
- return this._include(tableChainedName);
343
- }
344
- include(arg) {
345
- const parsed = FunctionUtil.parse(arg);
346
- const itemParamName = parsed.params[0];
347
- const tableChainedName = parsed.returnContent
348
- .replace(new RegExp(`${itemParamName}\\.`), "")
349
- .replace(/\[0]/g, "")
350
- .trim();
351
- return this._include(tableChainedName);
352
- }
353
- _include(tableChainedName) {
354
- if (!this.tableDef) {
355
- throw new Error("'Wrapping'된 이후에는 include 를 사용할 수 없습니다.");
356
- }
357
- const chain = tableChainedName.split(".");
358
- let result = this;
359
- let tableDef = this.tableDef;
360
- const asChainArr = [];
361
- for (const fkName of chain) {
362
- const prevAs = asChainArr.join(".");
363
- asChainArr.push(fkName);
364
- const as = asChainArr.join(".");
365
- // FK 정의 가져오기
366
- const fkDef = tableDef.foreignKeys.single((item) => item.propertyKey === fkName) ?? tableDef.referenceKeys.single((item) => item.propertyKey === fkName);
367
- const fktDef = tableDef.foreignKeyTargets.single((item) => item.propertyKey === fkName) ?? tableDef.referenceKeyTargets.single((item) => item.propertyKey === fkName);
368
- if (!fkDef && !fktDef) {
369
- throw new Error(`'${tableDef.name}.${as}'에 '@ForeignKey()'나 '@ForeignKeyTarget()'이 지정되지 않았습니다.`);
370
- }
371
- // FK
372
- if (fkDef) {
373
- // FK 대상 테이블의 정의 가져오기
374
- const fkTargetType = fkDef.targetTypeFwd();
375
- const fkTargetTableDef = DbDefinitionUtil.getTableDef(fkTargetType);
376
- if (fkDef.columnPropertyKeys.length !== fkTargetTableDef.columns.filter((item) => item.primaryKey !== undefined).length) {
377
- throw new Error(`'${tableDef.name}.${as}'의 FK 설정과 '${fkTargetTableDef.name}'의 PK 설정의 길이가 다릅니다.`);
378
- }
379
- // apply 실행
380
- result = result.joinSingle(fkTargetType, as, (q, en) => q.where((item) => {
381
- const lastEn = this._getEntityChainValue(en, prevAs);
382
- const whereQuery = [];
383
- for (let i = 0; i < fkDef.columnPropertyKeys.length; i++) {
384
- const columnPropertyKey = fkDef.columnPropertyKeys[i];
385
- if (columnPropertyKey.startsWith("=")) {
386
- const columnPropertyValue = columnPropertyKey.slice(1);
387
- whereQuery.push([this.db.qh.getQueryValue(item[fkTargetTableDef.columns[i].propertyKey]), " = ", columnPropertyValue]);
388
- }
389
- else {
390
- whereQuery.push(...[
391
- this.db.qh.isNotNull(lastEn[columnPropertyKey]),
392
- this.db.qh.equal(item[fkTargetTableDef.columns[i].propertyKey], lastEn[columnPropertyKey])
393
- ]);
394
- }
395
- }
396
- return whereQuery;
397
- }));
398
- tableDef = fkTargetTableDef;
399
- }
400
- // FKT
401
- else if (fktDef) {
402
- const fktSourceType = fktDef.sourceTypeFwd();
403
- const fktSourceTableDef = DbDefinitionUtil.getTableDef(fktSourceType);
404
- const fktSourceFkDef = fktSourceTableDef.foreignKeys.single((item) => item.propertyKey === fktDef.sourceKeyPropertyKey)
405
- ?? fktSourceTableDef.referenceKeys.single((item) => item.propertyKey === fktDef.sourceKeyPropertyKey);
406
- if (!fktSourceFkDef) {
407
- throw new Error(`'${fktSourceTableDef.name}.${fktDef.sourceKeyPropertyKey}'에 '@ForeignKey()'가 지정되지 않았습니다.`);
408
- }
409
- if (fktSourceFkDef.columnPropertyKeys.length !== tableDef.columns.filter((item) => item.primaryKey !== undefined).length) {
410
- throw new Error(`'${fktSourceTableDef.name}.${fktDef.sourceKeyPropertyKey}'의 FK 설정과 '${tableDef.name}'의 PK 설정의 길이가 다릅니다.`);
411
- }
412
- // JOIN 실행
413
- result = result.join(fktSourceType, as, (q, en) => q.where((item) => {
414
- const lastEn = this._getEntityChainValue(en, prevAs);
415
- const whereQuery = [];
416
- for (let i = 0; i < fktSourceFkDef.columnPropertyKeys.length; i++) {
417
- const columnPropertyKey = fktSourceFkDef.columnPropertyKeys[i];
418
- if (columnPropertyKey.startsWith("=")) {
419
- const columnPropertyValue = columnPropertyKey.slice(1);
420
- whereQuery.push([this.db.qh.getQueryValue(lastEn[tableDef.columns[i].propertyKey]), " = ", columnPropertyValue]);
421
- }
422
- else {
423
- whereQuery.push(...[
424
- this.db.qh.isNotNull(lastEn[tableDef.columns[i].propertyKey]),
425
- this.db.qh.equal(item[columnPropertyKey], lastEn[tableDef.columns[i].propertyKey])
426
- ]);
427
- }
428
- }
429
- return whereQuery;
430
- }));
431
- tableDef = fktSourceTableDef;
432
- }
433
- }
434
- return result;
435
- }
436
- search(fwd, searchText) {
437
- let result = new Queryable(this.db, this);
438
- const splitSearchText = searchText.trim().split(" ")
439
- .map((item) => item.trim())
440
- .filter((item) => Boolean(item));
441
- // WHERE
442
- const whereFnName = result._def.groupBy && result._def.groupBy.length > 0 ? "having" : "where";
443
- if (searchText.startsWith("<>")) {
444
- result = result[whereFnName]((item) => {
445
- const fieldOrArr = [];
446
- const fields = fwd(item);
447
- for (const field of fields) {
448
- const splitSearchTextWhereArr = [];
449
- for (const text of splitSearchText) {
450
- if (text.includes("*")) {
451
- splitSearchTextWhereArr.push(this.db.qh.notLike(this.db.qh.toLowerCase(field), text.substring(2).replace(/\*/g, "%").toLowerCase()));
452
- }
453
- else {
454
- splitSearchTextWhereArr.push(this.db.qh.notIncludes(this.db.qh.toLowerCase(field), text.substring(2).toLowerCase()));
455
- }
456
- }
457
- fieldOrArr.push(this.db.qh.and(splitSearchTextWhereArr));
458
- }
459
- return [this.db.qh.and(fieldOrArr)];
460
- });
461
- }
462
- else {
463
- result = result[whereFnName]((item) => {
464
- const fieldOrArr = [];
465
- const fields = fwd(item);
466
- for (const field of fields) {
467
- const splitSearchTextWhereArr = [];
468
- for (const text of splitSearchText) {
469
- if (text.includes("*")) {
470
- splitSearchTextWhereArr.push(this.db.qh.like(this.db.qh.toLowerCase(field), text.replace(/\*/g, "%").toLowerCase()));
471
- }
472
- else {
473
- splitSearchTextWhereArr.push(this.db.qh.includes(this.db.qh.toLowerCase(field), text.toLowerCase()));
474
- }
475
- }
476
- fieldOrArr.push(this.db.qh.and(splitSearchTextWhereArr));
477
- }
478
- return [this.db.qh.or(fieldOrArr)];
479
- });
480
- }
481
- return result;
482
- }
483
- searchEveryStringFields(searchText) {
484
- return this.search((en) => {
485
- const fields = [];
486
- const addFieldProc = (entity) => {
487
- for (const key of Object.keys(entity)) {
488
- const entityValue = entity[key];
489
- if (SdOrmUtil.canConvertToQueryValue(entityValue)) {
490
- const entityValueType = SdOrmUtil.getQueryValueType(entityValue);
491
- if (entityValueType === String) {
492
- fields.push(entityValue);
493
- }
494
- }
495
- else if (entityValue instanceof Array) {
496
- for (const entityValueItem of entityValue) {
497
- addFieldProc(entityValueItem);
498
- }
499
- }
500
- else if (!(entityValue instanceof QueryUnit)) {
501
- addFieldProc(entityValue);
502
- }
503
- }
504
- };
505
- addFieldProc(en);
506
- return fields;
507
- }, searchText);
508
- }
509
- wrap(tableType) {
510
- let clone;
511
- if (tableType !== undefined) {
512
- const cloneEntity = {};
513
- for (const key of Object.keys(this._entity)) {
514
- const entityValue = this._entity[key];
515
- if (SdOrmUtil.canConvertToQueryValue(entityValue)) {
516
- cloneEntity[key] = entityValue;
517
- }
518
- }
519
- clone = new Queryable(this.db, this, cloneEntity);
520
- clone._def.distinct = true;
521
- }
522
- else {
523
- clone = new Queryable(this.db, this);
524
- }
525
- const subFrom = clone.getSelectQueryDef();
526
- if (this.db.opt.dialect === "mssql" || this.db.opt.dialect === "mssql-azure") {
527
- if (subFrom.orderBy) {
528
- let seq = 0;
529
- for (const subOrderBy of subFrom.orderBy) {
530
- seq++;
531
- subFrom.select["__order_" + seq] = subOrderBy[0];
532
- }
533
- }
534
- }
535
- const currEntity = this._getParentEntity(clone._entity, this._as, undefined);
536
- const result = new Queryable(this.db, tableType, this._as, currEntity, { from: subFrom });
537
- if (this.db.opt.dialect === "mssql" || this.db.opt.dialect === "mssql-azure") {
538
- if (subFrom.orderBy && subFrom.orderBy.length > 0) {
539
- result._def.orderBy = [];
540
- let seq = 0;
541
- for (const subOrderBy of subFrom.orderBy) {
542
- seq++;
543
- result._def.orderBy.push(["__order_" + seq, subOrderBy[1]]);
544
- }
545
- if (!subFrom.limit) {
546
- delete subFrom.orderBy;
547
- }
548
- }
549
- }
550
- return result;
551
- }
552
- getSelectQueryDef() {
553
- const result = {};
554
- // FROM 구성
555
- result.from = this._def.from;
556
- // AS 구성
557
- result.as = this.db.qb.wrap(`TBL${this._as !== undefined ? `.${this._as}` : ""}`);
558
- // SELECT 필드 구성
559
- result.select = {};
560
- const addSelectValue = (key, value) => {
561
- if (SdOrmUtil.canConvertToQueryValue(value)) {
562
- if (typeof result.select === "undefined")
563
- throw new NeverEntryError();
564
- result.select[`${this.db.qb.wrap(key)}`] = this.db.qh.getQueryValue(value);
565
- }
566
- else if (value instanceof Array) {
567
- if (value.some((item) => SdOrmUtil.canConvertToQueryValue(item))) {
568
- throw new Error("SELECT 에 입력할 수 없는 정보가 입력되었습니다. (qh.equal 등은 qh.is 로 wrapping 해 주어야 사용할 수 있습니다.)");
569
- }
570
- else {
571
- for (const subKey of Object.keys(value[0]).orderBy()) {
572
- addSelectValue(`${key}.${subKey}`, value[0][subKey]);
573
- }
574
- }
575
- }
576
- else {
577
- for (const subKey of Object.keys(value).orderBy()) {
578
- addSelectValue(`${key}.${subKey}`, value[subKey]);
579
- }
580
- }
581
- };
582
- for (const entityKey of Object.keys(this._entity).orderBy()) {
583
- addSelectValue(entityKey, this._entity[entityKey]);
584
- }
585
- result.where = this._def.where;
586
- result.distinct = this._def.distinct;
587
- result.top = this._def.top;
588
- result.orderBy = this._def.orderBy;
589
- result.limit = this._def.limit;
590
- result.pivot = this._def.pivot;
591
- result.unpivot = this._def.unpivot;
592
- result.groupBy = this._def.groupBy;
593
- result.having = this._def.having;
594
- result.lock = this._def.lock;
595
- result.sample = this._def.sample;
596
- if (this._def.join) {
597
- const joins = ObjectUtil.clone(this._def.join);
598
- for (const join of joins) {
599
- // @ts-expect-error
600
- delete join.isSingle;
601
- }
602
- result.join = joins;
603
- }
604
- if (this._def.having && !(this._def.groupBy && this._def.groupBy.length > 0)) {
605
- throw new Error("'HAVING'을 사용하려면, 'GROUP BY'를 반드시 설정해야 합니다.");
606
- }
607
- if (this._def.limit && this._def.join && this._def.join.some((item) => !item.isSingle) && !this._def.groupBy && !this._isCustomEntity) {
608
- throw new Error("다수의 'RECORD'를 'JOIN'하는 쿼리와 'LIMIT'을 동시에 사용할 수 없습니다. 'LIMIT'을 먼저 사용하고, 'WRAP'한 이후에 'JOIN' 하거나, 'GROUP BY'도 함께 사용하세요.");
609
- }
610
- if (this._def.limit && (!this._def.orderBy || this._def.orderBy.length <= 0)) {
611
- throw new Error("'LIMIT'을 사용하려면, 'ORDER BY'를 반드시 설정해야 합니다.");
612
- }
613
- return ObjectUtil.clearUndefined(result);
614
- }
615
- _getParentEntity(fromEntity, rootAs, parentAs) {
616
- const result = {};
617
- for (const key of Object.keys(fromEntity)) {
618
- const entityValue = fromEntity[key];
619
- if (SdOrmUtil.canConvertToQueryValue(entityValue)) {
620
- result[key] = new QueryUnit(SdOrmUtil.getQueryValueType(entityValue), this.db.qb.wrap("TBL" + (rootAs !== undefined ? "." + rootAs : "")) + "." + this.db.qb.wrap((parentAs !== undefined ? `${parentAs}.` : "") + key));
621
- }
622
- else if (entityValue instanceof Array) {
623
- result[key] = [
624
- this._getParentEntity(entityValue[0], rootAs, (parentAs !== undefined ? parentAs + "." : "") + key)
625
- ];
626
- }
627
- else {
628
- result[key] = this._getParentEntity(entityValue, rootAs, (parentAs !== undefined ? parentAs + "." : "") + key);
629
- }
630
- }
631
- return result;
632
- }
633
- getInsertQueryDef(obj, outputColumns) {
634
- if (typeof this._def.from !== "string") {
635
- throw new Error("INSERT 할 TABLE 을 정확히 지정해야 합니다.");
636
- }
637
- if (this._def.join !== undefined) {
638
- throw new Error("INSERT 와 JOIN 를 함께 사용할 수 없습니다.");
639
- }
640
- if (this._isCustomEntity) {
641
- throw new Error("INSERT 와 SELECT 를 함께 사용할 수 없습니다.");
642
- }
643
- if (this._def.where !== undefined) {
644
- throw new Error("INSERT 와 WHERE 를 함께 사용할 수 없습니다.");
645
- }
646
- if (this._def.distinct !== undefined) {
647
- throw new Error("INSERT 와 DISTINCT 를 함께 사용할 수 없습니다.");
648
- }
649
- if (this._def.top !== undefined) {
650
- throw new Error("INSERT 와 TOP 를 함께 사용할 수 없습니다.");
651
- }
652
- if (this._def.orderBy !== undefined) {
653
- throw new Error("INSERT 와 ORDER BY 를 함께 사용할 수 없습니다.");
654
- }
655
- if (this._def.limit !== undefined) {
656
- throw new Error("INSERT 와 LIMIT 를 함께 사용할 수 없습니다.");
657
- }
658
- if (this._def.groupBy !== undefined) {
659
- throw new Error("INSERT 와 GROUP BY 를 함께 사용할 수 없습니다.");
660
- }
661
- if (this._def.having !== undefined) {
662
- throw new Error("INSERT 와 HAVING 를 함께 사용할 수 없습니다.");
663
- }
664
- const record = {};
665
- for (const key of Object.keys(obj)) {
666
- record[this.db.qb.wrap(key)] = this.db.qh.getQueryValue(obj[key]);
667
- }
668
- return ObjectUtil.clearUndefined({
669
- from: this._def.from,
670
- output: outputColumns?.map((item) => this.db.qb.wrap(item)),
671
- record
672
- });
673
- }
674
- getUpdateQueryDef(obj, outputColumns) {
675
- if (typeof this._def.from !== "string") {
676
- throw new Error("UPDATE 할 TABLE 을 정확히 지정해야 합니다.");
677
- }
678
- if (this._isCustomEntity) {
679
- throw new Error("UPDATE 와 SELECT 를 함께 사용할 수 없습니다.");
680
- }
681
- if (this._def.orderBy !== undefined) {
682
- throw new Error("UPDATE 와 ORDER BY 를 함께 사용할 수 없습니다.");
683
- }
684
- if (this._def.limit !== undefined) {
685
- throw new Error("UPDATE 와 LIMIT 를 함께 사용할 수 없습니다.");
686
- }
687
- if (this._def.groupBy !== undefined) {
688
- throw new Error("UPDATE 와 GROUP BY 를 함께 사용할 수 없습니다.");
689
- }
690
- if (this._def.having !== undefined) {
691
- throw new Error("UPDATE 와 HAVING 를 함께 사용할 수 없습니다.");
692
- }
693
- const record = {};
694
- for (const key of Object.keys(obj)) {
695
- record[this.db.qb.wrap(key)] = this.db.qh.getQueryValue(obj[key]);
696
- }
697
- let joinDefs;
698
- if (this._def.join) {
699
- const joins = ObjectUtil.clone(this._def.join);
700
- for (const join of joins) {
701
- delete join.isSingle;
702
- }
703
- joinDefs = joins;
704
- }
705
- return ObjectUtil.clearUndefined({
706
- top: this._def.top,
707
- from: this._def.from,
708
- record,
709
- output: outputColumns?.map((item) => this.db.qb.wrap(item)),
710
- as: this.db.qb.wrap(`TBL${this._as !== undefined ? `.${this._as}` : ""}`),
711
- join: joinDefs,
712
- where: this._def.where
713
- });
714
- }
715
- getInsertIfNotExistsQueryDef(insertObj, outputColumns) {
716
- if (this._def.join !== undefined) {
717
- throw new Error("INSERT IF NOT EXISTS 와 JOIN 를 함께 사용할 수 없습니다.");
718
- }
719
- if (typeof this._def.from !== "string") {
720
- throw new Error("INSERT IF NOT EXISTS 할 TABLE 을 정확히 지정해야 합니다.");
721
- }
722
- if (this._isCustomEntity) {
723
- throw new Error("INSERT IF NOT EXISTS 와 SELECT 를 함께 사용할 수 없습니다.");
724
- }
725
- if (this._def.distinct !== undefined) {
726
- throw new Error("INSERT IF NOT EXISTS 와 DISTINCT 를 함께 사용할 수 없습니다.");
727
- }
728
- if (this._def.top !== undefined) {
729
- throw new Error("INSERT IF NOT EXISTS 와 TOP 를 함께 사용할 수 없습니다.");
730
- }
731
- if (this._def.orderBy !== undefined) {
732
- throw new Error("INSERT IF NOT EXISTS 와 ORDER BY 를 함께 사용할 수 없습니다.");
733
- }
734
- if (this._def.limit !== undefined) {
735
- throw new Error("INSERT IF NOT EXISTS 와 LIMIT 를 함께 사용할 수 없습니다.");
736
- }
737
- if (this._def.groupBy !== undefined) {
738
- throw new Error("INSERT IF NOT EXISTS 와 GROUP BY 를 함께 사용할 수 없습니다.");
739
- }
740
- if (this._def.having !== undefined) {
741
- throw new Error("INSERT IF NOT EXISTS 와 HAVING 를 함께 사용할 수 없습니다.");
742
- }
743
- if (this._def.where === undefined || this._def.where.length < 1) {
744
- throw new Error("INSERT IF NOT EXISTS 시, WHERE 를 반드시 사용해야 합니다.");
745
- }
746
- const insertRecord = {};
747
- for (const key of Object.keys(insertObj)) {
748
- insertRecord[this.db.qb.wrap(`${key}`)] = this.db.qh.getQueryValue(insertObj[key]);
749
- }
750
- return ObjectUtil.clearUndefined({
751
- from: this._def.from,
752
- as: this.db.qb.wrap(`TBL${this._as !== undefined ? `.${this._as}` : ""}`),
753
- where: this._def.where,
754
- insertRecord,
755
- output: outputColumns?.map((item) => this.db.qb.wrap(item))
756
- });
757
- }
758
- getUpsertQueryDef(updateObj, insertObj, outputColumns) {
759
- if (this._def.join !== undefined) {
760
- throw new Error("UPSERT 와 JOIN 를 함께 사용할 수 없습니다.");
761
- }
762
- if (typeof this._def.from !== "string") {
763
- throw new Error("UPSERT 할 TABLE 을 정확히 지정해야 합니다.");
764
- }
765
- if (this._isCustomEntity) {
766
- throw new Error("UPSERT 와 SELECT 를 함께 사용할 수 없습니다.");
767
- }
768
- if (this._def.distinct !== undefined) {
769
- throw new Error("UPSERT 와 DISTINCT 를 함께 사용할 수 없습니다.");
770
- }
771
- if (this._def.top !== undefined) {
772
- throw new Error("UPSERT 와 TOP 를 함께 사용할 수 없습니다.");
773
- }
774
- if (this._def.orderBy !== undefined) {
775
- throw new Error("UPSERT 와 ORDER BY 를 함께 사용할 수 없습니다.");
776
- }
777
- if (this._def.limit !== undefined) {
778
- throw new Error("UPSERT 와 LIMIT 를 함께 사용할 수 없습니다.");
779
- }
780
- if (this._def.groupBy !== undefined) {
781
- throw new Error("UPSERT 와 GROUP BY 를 함께 사용할 수 없습니다.");
782
- }
783
- if (this._def.having !== undefined) {
784
- throw new Error("UPSERT 와 HAVING 를 함께 사용할 수 없습니다.");
785
- }
786
- if (this._def.where === undefined || this._def.where.length < 1) {
787
- throw new Error("UPSERT 시, WHERE 를 반드시 사용해야 합니다.");
788
- }
789
- // const updateRecordEntity = typeof updateObjOrFwd === "function" ? updateObjOrFwd(this._entity) : updateObjOrFwd;
790
- const updateRecord = {};
791
- for (const key of Object.keys(updateObj)) {
792
- updateRecord[this.db.qb.wrap(`${key}`)] = this.db.qh.getQueryValue(updateObj[key]);
793
- }
794
- // const insertObj = typeof insertObjOrFwd === "function" ? insertObjOrFwd(updateRecord as any) : insertObjOrFwd;
795
- let insertRecord = {};
796
- if (insertObj) {
797
- for (const key of Object.keys(insertObj)) {
798
- insertRecord[this.db.qb.wrap(`${key}`)] = this.db.qh.getQueryValue(insertObj[key]);
799
- }
800
- }
801
- else {
802
- insertRecord = ObjectUtil.clone(updateRecord);
803
- }
804
- return ObjectUtil.clearUndefined({
805
- from: this._def.from,
806
- as: this.db.qb.wrap(`TBL${this._as !== undefined ? `.${this._as}` : ""}`),
807
- where: this._def.where,
808
- updateRecord,
809
- insertRecord,
810
- output: outputColumns?.map((item) => this.db.qb.wrap(item))
811
- });
812
- }
813
- getDeleteQueryDef(outputColumns) {
814
- if (typeof this._def.from !== "string") {
815
- throw new Error("INSERT 할 TABLE 을 정확히 지정해야 합니다.");
816
- }
817
- if (this._isCustomEntity) {
818
- throw new Error("INSERT 와 SELECT 를 함께 사용할 수 없습니다.");
819
- }
820
- if (this._def.distinct !== undefined) {
821
- throw new Error("INSERT 와 DISTINCT 를 함께 사용할 수 없습니다.");
822
- }
823
- if (this._def.orderBy !== undefined) {
824
- throw new Error("INSERT 와 ORDER BY 를 함께 사용할 수 없습니다.");
825
- }
826
- if (this._def.limit !== undefined) {
827
- throw new Error("INSERT 와 LIMIT 를 함께 사용할 수 없습니다.");
828
- }
829
- if (this._def.groupBy !== undefined) {
830
- throw new Error("INSERT 와 GROUP BY 를 함께 사용할 수 없습니다.");
831
- }
832
- if (this._def.having !== undefined) {
833
- throw new Error("INSERT 와 HAVING 를 함께 사용할 수 없습니다.");
834
- }
835
- let joinDefs;
836
- if (this._def.join) {
837
- const joins = ObjectUtil.clone(this._def.join);
838
- for (const join of joins) {
839
- delete join.isSingle;
840
- }
841
- joinDefs = joins;
842
- }
843
- return ObjectUtil.clearUndefined({
844
- top: this._def.top,
845
- from: this._def.from,
846
- output: outputColumns?.map((item) => this.db.qb.wrap(item)),
847
- as: this.db.qb.wrap(`TBL${this._as !== undefined ? `.${this._as}` : ""}`),
848
- join: joinDefs,
849
- where: this._def.where
850
- });
851
- }
852
- async insertIntoAsync(tableType) {
853
- if (typeof this.db === "undefined") {
854
- throw new Error("'DbContext'가 설정되지 않은 쿼리는 실행할 수 없습니다.");
855
- }
856
- const def = this.getSelectQueryDef();
857
- const targetTableDef = DbDefinitionUtil.getTableDef(tableType);
858
- if (typeof targetTableDef === "undefined") {
859
- throw new Error(`'${tableType.name}'에 '@Table()'이 지정되지 않았습니다.`);
860
- }
861
- const targetTableName = this.db.qb.getTableName({
862
- ...this.db.opt.dialect === "sqlite" ? {} : {
863
- database: targetTableDef.database ?? this.db.opt.database,
864
- schema: targetTableDef.schema ?? this.db.opt.schema
865
- },
866
- name: targetTableDef.name
867
- });
868
- await this.db.executeDefsAsync([{
869
- type: "insertInto",
870
- ...def,
871
- target: targetTableName
872
- }]);
873
- }
874
- async resultAsync() {
875
- if (typeof this.db === "undefined") {
876
- throw new Error("'DbContext'가 설정되지 않은 쿼리는 실행할 수 없습니다.");
877
- }
878
- const def = this.getSelectQueryDef();
879
- // const cacheKey = JsonConvert.stringify(def)!;
880
- //
881
- // if (DbContext.selectCache.has(cacheKey)) {
882
- // try {
883
- // await Wait.until(() => DbContext.selectCache.get(cacheKey) !== undefined, undefined, 30000);
884
- // const cacheValue = DbContext.selectCache.get(cacheKey)!;
885
- //
886
- // clearTimeout(cacheValue.timeout);
887
- // cacheValue.timeout = setTimeout(() => {
888
- // DbContext.selectCache.delete(cacheKey);
889
- // }, DbContext.SELECT_CACHE_TIMEOUT);
890
- //
891
- // return cacheValue.result;
892
- // }
893
- // catch (err) {
894
- // // eslint-disable-next-line no-console
895
- // console.error(err);
896
- // }
897
- // }
898
- // DbContext.selectCache.set(cacheKey, undefined);
899
- const results = await this.db.executeDefsAsync([{ type: "select", ...def }], [this._getParseOption(undefined)]);
900
- // const timeout = setTimeout(() => {
901
- // DbContext.selectCache.delete(cacheKey);
902
- // }, DbContext.SELECT_CACHE_TIMEOUT);
903
- // DbContext.selectCache.set(cacheKey, { result: results[0] ?? [], timeout });
904
- return results[0];
905
- }
906
- async singleAsync() {
907
- const result = await this.resultAsync();
908
- if (result.length > 1) {
909
- throw new Error("복수의 쿼리결과가 있습니다.");
910
- }
911
- return result[0];
912
- }
913
- async countAsync() {
914
- if (this._def.distinct) {
915
- throw new Error("distinct 이후엔 'countAsync'를 사용할 수 없습니다."
916
- + " 사용하려면 distinct와 countAsync 사이에 wrap을 먼저 사용하거나,"
917
- + " distinct대신 groupBy와 qh.count 로 수동으로 처리하세요.");
918
- }
919
- const queryable = this.select(() => ({ cnt: new QueryUnit(Number, "COUNT(*)") })); /*.lock();*/
920
- delete queryable._def.orderBy;
921
- const item = await queryable.singleAsync();
922
- return (item?.cnt ?? 0);
923
- }
924
- async existsAsync() {
925
- // const cnt = await this.lock().countAsync();
926
- const cnt = await this.countAsync();
927
- return cnt > 0;
928
- }
929
- async bulkInsertAsync(arg) {
930
- const records = arg instanceof Array ? arg : [arg];
931
- if (typeof this.db === "undefined") {
932
- throw new Error("'DbContext'가 설정되지 않은 쿼리는 실행할 수 없습니다.");
933
- }
934
- // DbContext.selectCache.clear();
935
- if (!this.tableDef) {
936
- throw new Error("'Wrapping'된 이후에는 테이블의 정보를 가져올 수 없습니다.");
937
- }
938
- const columnDefs = this.tableDef.columns.map((col) => ({
939
- name: col.name,
940
- dataType: this.db.qh.type(col.dataType ?? col.typeFwd()),
941
- autoIncrement: col.autoIncrement,
942
- nullable: col.nullable
943
- }));
944
- await this.db.bulkInsertAsync(this.tableName, columnDefs, records.map((item) => {
945
- const result = {};
946
- for (const key of Object.keys(item)) {
947
- result[key] = this.db.qh.getBulkInsertQueryValue(item[key]);
948
- }
949
- return result;
950
- }));
951
- }
952
- async insertAsync(records, outputColumns) {
953
- return await this._insertAsync(false, records, outputColumns);
954
- }
955
- async insertWithoutFkCheckAsync(records, outputColumns) {
956
- return await this._insertAsync(true, records, outputColumns);
957
- }
958
- async _insertAsync(ignoreFk, records, outputColumns) {
959
- if (records.length === 0 && outputColumns !== undefined)
960
- return [];
961
- if (records.length === 0 && outputColumns === undefined)
962
- return undefined;
963
- const { defs, dataIndexes } = this._getInsertDefs(ignoreFk, records, outputColumns);
964
- const parseOption = outputColumns ? this._getParseOption(outputColumns) : undefined;
965
- return (await this.db.executeDefsAsync(defs, defs.map((def, i) => (dataIndexes.includes(i) ? parseOption : undefined)))).filter((item, i) => dataIndexes.includes(i)).map((item) => item[0]);
966
- }
967
- insertPrepare(records) {
968
- this._insertPrepare(false, records);
969
- }
970
- insertWithoutFkCheckPrepare(records) {
971
- this._insertPrepare(true, records);
972
- }
973
- _insertPrepare(ignoreFk, records) {
974
- if (records.length === 0)
975
- return;
976
- const { defs } = this._getInsertDefs(ignoreFk, records, undefined);
977
- this.db.prepareDefs.push(...defs);
978
- }
979
- _getInsertDefs(ignoreFk, records, outputColumns) {
980
- if (records.length < 1) {
981
- throw new Error("데이터 누락");
982
- }
983
- if (typeof this.db === "undefined") {
984
- throw new Error("'DbContext'가 설정되지 않은 쿼리는 실행할 수 없습니다.");
985
- }
986
- if (!this.tableDef) {
987
- throw new Error("'Wrapping'된 이후에는 테이블의 정보를 가져올 수 없습니다.");
988
- }
989
- // DbContext.selectCache.clear();
990
- const pkColNames = this.tableDef.columns.filter((item) => item.primaryKey !== undefined).map((item) => item.name);
991
- const aiColNames = this.tableDef.columns.filter((item) => item.autoIncrement).map((item) => item.name);
992
- const dataIndexes = [];
993
- const defs = [];
994
- for (let i = 0; i < records.length; i++) {
995
- const record = records[i];
996
- const queryDef = this.getInsertQueryDef(record, outputColumns);
997
- defs.push({
998
- type: "insert",
999
- ...queryDef
1000
- });
1001
- if (this.db.opt.dialect === "mysql" && outputColumns) {
1002
- const selectObj = outputColumns.toObject((colName) => this.db.qb.wrap(colName), (colName) => this.db.qb.wrap(colName));
1003
- if (pkColNames.length === 1 && aiColNames.length === 1
1004
- && pkColNames[0] === aiColNames[0]
1005
- && !Object.keys(record).includes(aiColNames[0])) {
1006
- const pkColName = pkColNames[0];
1007
- defs.push({
1008
- type: "select",
1009
- from: this._def.from,
1010
- select: selectObj,
1011
- where: [[this.db.qb.wrap(pkColName), " = ", "LAST_INSERT_ID()"]]
1012
- });
1013
- }
1014
- else {
1015
- defs.push({
1016
- type: "select",
1017
- from: this._def.from,
1018
- select: selectObj,
1019
- where: pkColNames.map((pkColName) => [[this.db.qb.wrap(pkColName), " = ", this.db.qh.getQueryValue(record[pkColName])]])
1020
- });
1021
- }
1022
- dataIndexes.push((i * 2) + 1);
1023
- }
1024
- else if (outputColumns) {
1025
- dataIndexes.push(i);
1026
- }
1027
- }
1028
- if (ignoreFk) {
1029
- defs.insert(0, {
1030
- type: "configForeignKeyCheck",
1031
- table: this.tableNameDef,
1032
- useCheck: false
1033
- });
1034
- for (let i = 0; i < dataIndexes.length; i++) {
1035
- dataIndexes[i]++;
1036
- }
1037
- defs.push({
1038
- type: "configForeignKeyCheck",
1039
- table: this.tableNameDef,
1040
- useCheck: true
1041
- });
1042
- }
1043
- if (this.db.opt.dialect === "mssql" || this.db.opt.dialect === "mssql-azure") {
1044
- const hasSomeAIColVal = records.some((record) => Object.keys(record).some((item) => aiColNames.includes(item)));
1045
- if (hasSomeAIColVal) {
1046
- defs.insert(0, {
1047
- type: "configIdentityInsert",
1048
- ...{
1049
- table: this.tableNameDef,
1050
- state: "on"
1051
- }
1052
- });
1053
- for (let i = 0; i < dataIndexes.length; i++) {
1054
- dataIndexes[i]++;
1055
- }
1056
- defs.push({
1057
- type: "configIdentityInsert",
1058
- ...{
1059
- table: this.tableNameDef,
1060
- state: "off"
1061
- }
1062
- });
1063
- }
1064
- }
1065
- return { defs, dataIndexes };
1066
- }
1067
- async updateAsync(recordFwd, outputColumns) {
1068
- const record = await recordFwd(this._entity);
1069
- const { defs, dataIndex } = this._getUpdateDefs(record, outputColumns);
1070
- const parseOption = outputColumns ? this._getParseOption(outputColumns) : undefined;
1071
- return (await this.db.executeDefsAsync(defs, defs.map((def, i) => (dataIndex === i ? parseOption : undefined))))[dataIndex];
1072
- }
1073
- updatePrepare(recordFwd) {
1074
- const record = recordFwd(this._entity);
1075
- const { defs } = this._getUpdateDefs(record, undefined);
1076
- this.db.prepareDefs.push(...defs);
1077
- }
1078
- _getUpdateDefs(record, outputColumns) {
1079
- if (typeof this.db === "undefined") {
1080
- throw new Error("'DbContext'가 설정되지 않은 쿼리는 실행할 수 없습니다.");
1081
- }
1082
- if (!this.tableDef) {
1083
- throw new Error("'Wrapping'된 이후에는 편집 쿼리를 실행할 수 없습니다.");
1084
- }
1085
- // DbContext.selectCache.clear();
1086
- let dataIndex;
1087
- const defs = [];
1088
- const queryDef = this.getUpdateQueryDef(record, outputColumns);
1089
- defs.push({
1090
- type: "update",
1091
- ...queryDef
1092
- });
1093
- if (this.db.opt.dialect === "mysql" && outputColumns) {
1094
- const selectObj = outputColumns.toObject((colName) => this.db.qb.wrap(colName), (colName) => this.db.qb.wrap(colName));
1095
- defs.push({
1096
- type: "select",
1097
- ...this.getSelectQueryDef(),
1098
- select: selectObj
1099
- });
1100
- dataIndex = 1;
1101
- }
1102
- else {
1103
- dataIndex = 0;
1104
- }
1105
- return { defs, dataIndex };
1106
- }
1107
- async deleteAsync(outputColumns) {
1108
- const { defs, dataIndex } = this._getDeleteDefs(outputColumns);
1109
- const parseOption = outputColumns ? this._getParseOption(outputColumns) : undefined;
1110
- return (await this.db.executeDefsAsync(defs, defs.map((def, i) => (dataIndex === i ? parseOption : undefined))))[dataIndex];
1111
- }
1112
- deletePrepare() {
1113
- const { defs } = this._getDeleteDefs(undefined);
1114
- this.db.prepareDefs.push(...defs);
1115
- }
1116
- _getDeleteDefs(outputColumns) {
1117
- if (typeof this.db === "undefined") {
1118
- throw new Error("'DbContext'가 설정되지 않은 쿼리는 실행할 수 없습니다.");
1119
- }
1120
- if (!this.tableDef) {
1121
- throw new Error("'Wrapping'된 이후에는 편집 쿼리를 실행할 수 없습니다.");
1122
- }
1123
- // DbContext.selectCache.clear();
1124
- const defs = [];
1125
- const queryDef = this.getDeleteQueryDef(outputColumns);
1126
- defs.push({
1127
- type: "delete",
1128
- ...queryDef
1129
- });
1130
- if (this.db.opt.dialect === "mysql" && outputColumns) {
1131
- const selectObj = outputColumns.toObject((colName) => this.db.qb.wrap(colName), (colName) => this.db.qb.wrap(colName));
1132
- defs.insert(0, {
1133
- type: "select",
1134
- ...this.getSelectQueryDef(),
1135
- select: selectObj
1136
- });
1137
- }
1138
- return { defs, dataIndex: 0 };
1139
- }
1140
- async upsertAsync(arg1, arg2, arg3) {
1141
- const updateFwd = arg1;
1142
- const insertFwd = typeof arg2 === "function" ? arg2 : undefined;
1143
- const outputColumns = arg2 instanceof Array ? arg2 : arg3;
1144
- const updateRecord = await updateFwd(this._entity);
1145
- const insertRecord = (insertFwd ? await insertFwd(updateRecord) : ObjectUtil.clone(updateRecord));
1146
- const { defs, dataIndex } = this._getUpsertDefs(updateRecord, insertRecord, outputColumns);
1147
- const parseOption = outputColumns ? this._getParseOption(outputColumns) : undefined;
1148
- const result = (await this.db.executeDefsAsync(defs, defs.map((def, i) => (dataIndex === i ? parseOption : undefined))));
1149
- return result[dataIndex];
1150
- }
1151
- upsertPrepare(updateObjOrFwd, insertObjOrFwd) {
1152
- const updateRecord = (typeof updateObjOrFwd === "function" ? updateObjOrFwd(this._entity) : updateObjOrFwd);
1153
- const insertRecord = (insertObjOrFwd
1154
- ? (typeof insertObjOrFwd === "function" ? insertObjOrFwd(updateRecord) : insertObjOrFwd)
1155
- : updateRecord);
1156
- const { defs } = this._getUpsertDefs(updateRecord, insertRecord, undefined);
1157
- this.db.prepareDefs.push(...defs);
1158
- }
1159
- _getUpsertDefs(updateRecord, insertRecord, outputColumns) {
1160
- if (typeof this.db === "undefined") {
1161
- throw new Error("'DbContext'가 설정되지 않은 쿼리는 실행할 수 없습니다.");
1162
- }
1163
- if (!this.tableDef) {
1164
- throw new Error("'Wrapping'된 이후에는 편집 쿼리를 실행할 수 없습니다.");
1165
- }
1166
- // DbContext.selectCache.clear();
1167
- const pkColNames = this.tableDef.columns.filter((item) => item.primaryKey !== undefined).map((item) => item.name);
1168
- const aiColNames = this.tableDef.columns.filter((item) => item.autoIncrement).map((item) => item.name);
1169
- let dataIndex;
1170
- const defs = [];
1171
- const queryDef = this.getUpsertQueryDef(updateRecord, insertRecord, outputColumns);
1172
- defs.push({
1173
- type: "upsert",
1174
- ...queryDef
1175
- });
1176
- if (this.db.opt.dialect === "mysql" && outputColumns) {
1177
- const selectObj = outputColumns.toObject((colName) => this.db.qb.wrap(colName), (colName) => this.db.qb.wrap(colName));
1178
- if (pkColNames.length === 1 && aiColNames.length === 1
1179
- && pkColNames[0] === aiColNames[0]
1180
- && !Object.keys(insertRecord).includes(aiColNames[0])) {
1181
- const pkColName = pkColNames[0];
1182
- defs.push({
1183
- type: "select",
1184
- ...this.getSelectQueryDef(),
1185
- select: selectObj,
1186
- where: [[this.db.qb.wrap(pkColName), " = ", "LAST_INSERT_ID()"]]
1187
- });
1188
- }
1189
- else {
1190
- defs.push({
1191
- type: "select",
1192
- ...this.getSelectQueryDef(),
1193
- select: selectObj
1194
- });
1195
- }
1196
- dataIndex = 1;
1197
- }
1198
- else {
1199
- dataIndex = 0;
1200
- }
1201
- if (this.db.opt.dialect !== "mysql") {
1202
- const hasSomeAIColVal = Object.keys(insertRecord).some((item) => aiColNames.includes(item));
1203
- if (hasSomeAIColVal) {
1204
- defs.insert(0, {
1205
- type: "configIdentityInsert",
1206
- ...{
1207
- table: this.tableNameDef,
1208
- state: "on"
1209
- }
1210
- });
1211
- dataIndex++;
1212
- defs.push({
1213
- type: "configIdentityInsert",
1214
- ...{
1215
- table: this.tableNameDef,
1216
- state: "off"
1217
- }
1218
- });
1219
- }
1220
- }
1221
- return { defs, dataIndex };
1222
- }
1223
- /*public async insertIfNotExistsAsync(records: TInsertObject<T>[]): Promise<void>;
1224
- public async insertIfNotExistsAsync<OK extends keyof T>(records: TInsertObject<T>[], outputColumns: OK[]): Promise<{ [K in OK]: T[K] }[]>;
1225
- public async insertIfNotExistsAsync<OK extends keyof T>(records: TInsertObject<T>[], outputColumns?: OK[]): Promise<{ [K in OK]: T[K] }[] | void> {
1226
- if (typeof this.db === "undefined") {
1227
- throw new Error("'DbContext'가 설정되지 않은 쿼리는 실행할 수 없습니다.");
1228
- }
1229
- if (!this._tableDef) {
1230
- throw new Error("'Wrapping'된 이후에는 편집 쿼리를 실행할 수 없습니다.");
1231
- }
1232
- DbContext.selectCache.clear();
1233
-
1234
- const queryDefs = records.map((record) => this.getInsertIfNotExistsQueryDef(record, outputColumns));
1235
- const parseOption = outputColumns ? this._getParseOption(outputColumns) : undefined;
1236
-
1237
- if (this.db.opt.dialect === "mysql") {
1238
- throw new NotImplementError("mysql 미구현");
1239
- }
1240
- else {
1241
- const aiColNames = this._tableDef.columns.filter((item) => item.autoIncrement).map((item) => item.name);
1242
- const hasAutoIncreaseColumnValue = Object.keys(records[0]).some((item) => aiColNames.includes(item));
1243
-
1244
- if (hasAutoIncreaseColumnValue) {
1245
- return (
1246
- await this.db.executeDefsAsync([
1247
- {
1248
- type: "configIdentityInsert",
1249
- ...{
1250
- table: {
1251
- database: this._tableDef.database ?? this.db.opt.database,
1252
- schema: this._tableDef.schema ?? this.db.opt.schema,
1253
- name: this._tableDef.name
1254
- },
1255
- state: "on"
1256
- }
1257
- },
1258
- ...queryDefs.map((queryDef) => ({
1259
- type: "insertIfNotExists" as const,
1260
- ...queryDef
1261
- })),
1262
- {
1263
- type: "configIdentityInsert",
1264
- ...{
1265
- table: {
1266
- database: this._tableDef.database ?? this.db.opt.database,
1267
- schema: this._tableDef.schema ?? this.db.opt.schema,
1268
- name: this._tableDef.name
1269
- },
1270
- state: "off"
1271
- }
1272
- }
1273
- ], [undefined, ...queryDefs.map(() => parseOption), undefined])
1274
- ).slice(1, -1).map((item) => item[0]);
1275
- }
1276
-
1277
- return (await this.db.executeDefsAsync(
1278
- queryDefs.map((queryDef) => ({
1279
- type: "insertIfNotExists" as const,
1280
- ...queryDef
1281
- })),
1282
- queryDefs.map(() => parseOption)
1283
- )).map((item) => item[0]);
1284
- }
1285
- }*/
1286
- configIdentityInsert(state) {
1287
- if (typeof this.db === "undefined") {
1288
- throw new Error("'DbContext'가 설정되지 않은 쿼리는 실행할 수 없습니다.");
1289
- }
1290
- if (!this.tableDef) {
1291
- throw new Error("'Wrapping'된 이후에는 테이블의 정보를 가져올 수 없습니다.");
1292
- }
1293
- this.db.prepareDefs.push(...[
1294
- {
1295
- type: "configIdentityInsert",
1296
- table: this.tableNameDef,
1297
- state
1298
- }
1299
- ]);
1300
- }
1301
- _getParseOption(columns) {
1302
- const result = {
1303
- columns: {},
1304
- joins: {}
1305
- };
1306
- const configuration = (entity, parentKeys) => {
1307
- for (const key of Object.keys(ObjectUtil.clearUndefined(entity))) {
1308
- const fullKeyArr = parentKeys.concat([key]);
1309
- const fullKey = fullKeyArr.join(".");
1310
- if (columns && !columns.includes(fullKey))
1311
- continue;
1312
- try {
1313
- if (typeof entity[key] !== "undefined" && SdOrmUtil.canConvertToQueryValue(entity[key])) {
1314
- result.columns[fullKey] = { dataType: SdOrmUtil.getQueryValueType(entity[key]).name };
1315
- }
1316
- else if (entity[key] instanceof Array) {
1317
- result.joins[fullKey] = { isSingle: false };
1318
- configuration(entity[key][0], fullKeyArr);
1319
- }
1320
- else {
1321
- result.joins[fullKey] = { isSingle: true };
1322
- configuration(entity[key], fullKeyArr);
1323
- }
1324
- }
1325
- catch (err) {
1326
- if (err instanceof Error) {
1327
- err.message += `\n==> [${key}]`;
1328
- throw err;
1329
- }
1330
- else {
1331
- throw err;
1332
- }
1333
- }
1334
- }
1335
- };
1336
- configuration(this._entity, []);
1337
- return result;
1338
- }
1339
- _setEntityChainValue(obj, chain, value) {
1340
- const split = chain.split(".");
1341
- let curr = obj;
1342
- for (const splitItem of split.slice(0, -1)) {
1343
- if (curr[splitItem] instanceof Array) {
1344
- curr = curr[splitItem][0];
1345
- }
1346
- else {
1347
- curr = curr[splitItem];
1348
- }
1349
- }
1350
- const last = split.last();
1351
- if (last === undefined) {
1352
- throw new NeverEntryError();
1353
- }
1354
- curr[last] = value;
1355
- }
1356
- _getEntityChainValue(obj, chain, optional) {
1357
- if (chain === "")
1358
- return obj;
1359
- const split = chain.split(".");
1360
- let result = obj;
1361
- for (const splitItem of split) {
1362
- if (optional && result === undefined) {
1363
- result = undefined;
1364
- }
1365
- else {
1366
- result = result[splitItem];
1367
- }
1368
- if (result instanceof Array) {
1369
- result = result[0];
1370
- }
1371
- }
1372
- return result;
1373
- }
1374
- }
1375
- //# sourceMappingURL=Queryable.js.map