@simplysm/orm-common 13.0.100 → 14.0.4

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 (246) hide show
  1. package/README.md +90 -147
  2. package/dist/create-db-context.d.ts +10 -10
  3. package/dist/create-db-context.js +312 -276
  4. package/dist/create-db-context.js.map +1 -6
  5. package/dist/ddl/column-ddl.d.ts +4 -4
  6. package/dist/ddl/column-ddl.js +41 -35
  7. package/dist/ddl/column-ddl.js.map +1 -6
  8. package/dist/ddl/initialize.d.ts +17 -17
  9. package/dist/ddl/initialize.js +200 -142
  10. package/dist/ddl/initialize.js.map +1 -6
  11. package/dist/ddl/relation-ddl.d.ts +6 -6
  12. package/dist/ddl/relation-ddl.js +55 -48
  13. package/dist/ddl/relation-ddl.js.map +1 -6
  14. package/dist/ddl/schema-ddl.d.ts +4 -4
  15. package/dist/ddl/schema-ddl.js +21 -15
  16. package/dist/ddl/schema-ddl.js.map +1 -6
  17. package/dist/ddl/table-ddl.d.ts +20 -20
  18. package/dist/ddl/table-ddl.js +139 -93
  19. package/dist/ddl/table-ddl.js.map +1 -6
  20. package/dist/define-db-context.js +10 -13
  21. package/dist/define-db-context.js.map +1 -6
  22. package/dist/errors/db-transaction-error.d.ts +15 -15
  23. package/dist/errors/db-transaction-error.d.ts.map +1 -1
  24. package/dist/errors/db-transaction-error.js +53 -19
  25. package/dist/errors/db-transaction-error.js.map +1 -6
  26. package/dist/exec/executable.d.ts +23 -23
  27. package/dist/exec/executable.js +94 -40
  28. package/dist/exec/executable.js.map +1 -6
  29. package/dist/exec/queryable.d.ts +97 -97
  30. package/dist/exec/queryable.js +1310 -1204
  31. package/dist/exec/queryable.js.map +1 -6
  32. package/dist/exec/search-parser.d.ts +31 -31
  33. package/dist/exec/search-parser.d.ts.map +1 -1
  34. package/dist/exec/search-parser.js +158 -59
  35. package/dist/exec/search-parser.js.map +1 -6
  36. package/dist/expr/expr-unit.d.ts +4 -4
  37. package/dist/expr/expr-unit.js +24 -18
  38. package/dist/expr/expr-unit.js.map +1 -6
  39. package/dist/expr/expr.d.ts +108 -108
  40. package/dist/expr/expr.js +1872 -1844
  41. package/dist/expr/expr.js.map +1 -6
  42. package/dist/index.js +23 -1
  43. package/dist/index.js.map +1 -6
  44. package/dist/models/system-migration.js +7 -7
  45. package/dist/models/system-migration.js.map +1 -6
  46. package/dist/query-builder/base/expr-renderer-base.d.ts +10 -10
  47. package/dist/query-builder/base/expr-renderer-base.js +27 -21
  48. package/dist/query-builder/base/expr-renderer-base.js.map +1 -6
  49. package/dist/query-builder/base/query-builder-base.d.ts +21 -21
  50. package/dist/query-builder/base/query-builder-base.d.ts.map +1 -1
  51. package/dist/query-builder/base/query-builder-base.js +90 -80
  52. package/dist/query-builder/base/query-builder-base.js.map +1 -6
  53. package/dist/query-builder/mssql/mssql-expr-renderer.d.ts +5 -5
  54. package/dist/query-builder/mssql/mssql-expr-renderer.d.ts.map +1 -1
  55. package/dist/query-builder/mssql/mssql-expr-renderer.js +447 -420
  56. package/dist/query-builder/mssql/mssql-expr-renderer.js.map +1 -6
  57. package/dist/query-builder/mssql/mssql-query-builder.d.ts +2 -2
  58. package/dist/query-builder/mssql/mssql-query-builder.d.ts.map +1 -1
  59. package/dist/query-builder/mssql/mssql-query-builder.js +483 -443
  60. package/dist/query-builder/mssql/mssql-query-builder.js.map +1 -6
  61. package/dist/query-builder/mysql/mysql-expr-renderer.d.ts +5 -5
  62. package/dist/query-builder/mysql/mysql-expr-renderer.d.ts.map +1 -1
  63. package/dist/query-builder/mysql/mysql-expr-renderer.js +451 -419
  64. package/dist/query-builder/mysql/mysql-expr-renderer.js.map +1 -6
  65. package/dist/query-builder/mysql/mysql-query-builder.d.ts +10 -10
  66. package/dist/query-builder/mysql/mysql-query-builder.d.ts.map +1 -1
  67. package/dist/query-builder/mysql/mysql-query-builder.js +570 -479
  68. package/dist/query-builder/mysql/mysql-query-builder.js.map +1 -6
  69. package/dist/query-builder/postgresql/postgresql-expr-renderer.d.ts +5 -5
  70. package/dist/query-builder/postgresql/postgresql-expr-renderer.d.ts.map +1 -1
  71. package/dist/query-builder/postgresql/postgresql-expr-renderer.js +449 -422
  72. package/dist/query-builder/postgresql/postgresql-expr-renderer.js.map +1 -6
  73. package/dist/query-builder/postgresql/postgresql-query-builder.d.ts +8 -8
  74. package/dist/query-builder/postgresql/postgresql-query-builder.d.ts.map +1 -1
  75. package/dist/query-builder/postgresql/postgresql-query-builder.js +511 -460
  76. package/dist/query-builder/postgresql/postgresql-query-builder.js.map +1 -6
  77. package/dist/query-builder/query-builder.d.ts +1 -1
  78. package/dist/query-builder/query-builder.js +13 -13
  79. package/dist/query-builder/query-builder.js.map +1 -6
  80. package/dist/schema/factory/column-builder.d.ts +84 -84
  81. package/dist/schema/factory/column-builder.js +248 -185
  82. package/dist/schema/factory/column-builder.js.map +1 -6
  83. package/dist/schema/factory/index-builder.d.ts +38 -38
  84. package/dist/schema/factory/index-builder.js +144 -85
  85. package/dist/schema/factory/index-builder.js.map +1 -6
  86. package/dist/schema/factory/relation-builder.d.ts +99 -99
  87. package/dist/schema/factory/relation-builder.d.ts.map +1 -1
  88. package/dist/schema/factory/relation-builder.js +274 -136
  89. package/dist/schema/factory/relation-builder.js.map +1 -6
  90. package/dist/schema/procedure-builder.d.ts +51 -51
  91. package/dist/schema/procedure-builder.d.ts.map +1 -1
  92. package/dist/schema/procedure-builder.js +205 -131
  93. package/dist/schema/procedure-builder.js.map +1 -6
  94. package/dist/schema/table-builder.d.ts +55 -55
  95. package/dist/schema/table-builder.d.ts.map +1 -1
  96. package/dist/schema/table-builder.js +274 -205
  97. package/dist/schema/table-builder.js.map +1 -6
  98. package/dist/schema/view-builder.d.ts +44 -44
  99. package/dist/schema/view-builder.d.ts.map +1 -1
  100. package/dist/schema/view-builder.js +189 -116
  101. package/dist/schema/view-builder.js.map +1 -6
  102. package/dist/types/column.d.ts +21 -21
  103. package/dist/types/column.js +60 -30
  104. package/dist/types/column.js.map +1 -6
  105. package/dist/types/db-context-def.d.ts +9 -9
  106. package/dist/types/db-context-def.js +2 -1
  107. package/dist/types/db-context-def.js.map +1 -6
  108. package/dist/types/db.d.ts +47 -47
  109. package/dist/types/db.js +15 -5
  110. package/dist/types/db.js.map +1 -6
  111. package/dist/types/expr.d.ts +81 -81
  112. package/dist/types/expr.d.ts.map +1 -1
  113. package/dist/types/expr.js +3 -1
  114. package/dist/types/expr.js.map +1 -6
  115. package/dist/types/query-def.d.ts +46 -46
  116. package/dist/types/query-def.d.ts.map +1 -1
  117. package/dist/types/query-def.js +31 -24
  118. package/dist/types/query-def.js.map +1 -6
  119. package/dist/utils/result-parser.d.ts +11 -11
  120. package/dist/utils/result-parser.js +362 -221
  121. package/dist/utils/result-parser.js.map +1 -6
  122. package/docs/core.md +117 -145
  123. package/docs/expression.md +186 -203
  124. package/docs/query-builder.md +75 -42
  125. package/docs/queryable.md +189 -151
  126. package/docs/schema-builders.md +172 -283
  127. package/docs/types.md +229 -173
  128. package/package.json +7 -5
  129. package/src/create-db-context.ts +31 -31
  130. package/src/ddl/column-ddl.ts +4 -4
  131. package/src/ddl/initialize.ts +38 -38
  132. package/src/ddl/relation-ddl.ts +6 -6
  133. package/src/ddl/schema-ddl.ts +4 -4
  134. package/src/ddl/table-ddl.ts +24 -24
  135. package/src/errors/db-transaction-error.ts +13 -13
  136. package/src/exec/executable.ts +25 -25
  137. package/src/exec/queryable.ts +152 -152
  138. package/src/exec/search-parser.ts +50 -50
  139. package/src/expr/expr-unit.ts +4 -4
  140. package/src/expr/expr.ts +118 -118
  141. package/src/index.ts +8 -8
  142. package/src/models/system-migration.ts +1 -1
  143. package/src/query-builder/base/expr-renderer-base.ts +21 -21
  144. package/src/query-builder/base/query-builder-base.ts +33 -33
  145. package/src/query-builder/mssql/mssql-expr-renderer.ts +28 -28
  146. package/src/query-builder/mssql/mssql-query-builder.ts +37 -37
  147. package/src/query-builder/mysql/mysql-expr-renderer.ts +29 -29
  148. package/src/query-builder/mysql/mysql-query-builder.ts +70 -70
  149. package/src/query-builder/postgresql/postgresql-expr-renderer.ts +22 -22
  150. package/src/query-builder/postgresql/postgresql-query-builder.ts +54 -54
  151. package/src/query-builder/query-builder.ts +1 -1
  152. package/src/schema/factory/column-builder.ts +86 -86
  153. package/src/schema/factory/index-builder.ts +38 -38
  154. package/src/schema/factory/relation-builder.ts +102 -102
  155. package/src/schema/procedure-builder.ts +52 -52
  156. package/src/schema/table-builder.ts +56 -56
  157. package/src/schema/view-builder.ts +47 -47
  158. package/src/types/column.ts +24 -24
  159. package/src/types/db-context-def.ts +15 -15
  160. package/src/types/db.ts +50 -50
  161. package/src/types/expr.ts +103 -103
  162. package/src/types/query-def.ts +50 -50
  163. package/src/utils/result-parser.ts +88 -88
  164. package/docs/utilities.md +0 -27
  165. package/tests/db-context/create-db-context.spec.ts +0 -193
  166. package/tests/db-context/define-db-context.spec.ts +0 -17
  167. package/tests/ddl/basic.expected.ts +0 -341
  168. package/tests/ddl/basic.spec.ts +0 -557
  169. package/tests/ddl/column-builder.expected.ts +0 -310
  170. package/tests/ddl/column-builder.spec.ts +0 -525
  171. package/tests/ddl/index-builder.expected.ts +0 -38
  172. package/tests/ddl/index-builder.spec.ts +0 -148
  173. package/tests/ddl/procedure-builder.expected.ts +0 -52
  174. package/tests/ddl/procedure-builder.spec.ts +0 -128
  175. package/tests/ddl/relation-builder.expected.ts +0 -36
  176. package/tests/ddl/relation-builder.spec.ts +0 -171
  177. package/tests/ddl/table-builder.expected.ts +0 -113
  178. package/tests/ddl/table-builder.spec.ts +0 -399
  179. package/tests/ddl/view-builder.expected.ts +0 -38
  180. package/tests/ddl/view-builder.spec.ts +0 -116
  181. package/tests/dml/delete.expected.ts +0 -96
  182. package/tests/dml/delete.spec.ts +0 -127
  183. package/tests/dml/insert.expected.ts +0 -192
  184. package/tests/dml/insert.spec.ts +0 -210
  185. package/tests/dml/update.expected.ts +0 -176
  186. package/tests/dml/update.spec.ts +0 -222
  187. package/tests/dml/upsert.expected.ts +0 -215
  188. package/tests/dml/upsert.spec.ts +0 -190
  189. package/tests/errors/queryable-errors.spec.ts +0 -126
  190. package/tests/escape.spec.ts +0 -59
  191. package/tests/examples/pivot.expected.ts +0 -211
  192. package/tests/examples/pivot.spec.ts +0 -200
  193. package/tests/examples/sampling.expected.ts +0 -69
  194. package/tests/examples/sampling.spec.ts +0 -42
  195. package/tests/examples/unpivot.expected.ts +0 -120
  196. package/tests/examples/unpivot.spec.ts +0 -161
  197. package/tests/exec/search-parser.spec.ts +0 -267
  198. package/tests/executable/basic.expected.ts +0 -18
  199. package/tests/executable/basic.spec.ts +0 -54
  200. package/tests/expr/comparison.expected.ts +0 -282
  201. package/tests/expr/comparison.spec.ts +0 -334
  202. package/tests/expr/conditional.expected.ts +0 -134
  203. package/tests/expr/conditional.spec.ts +0 -249
  204. package/tests/expr/date.expected.ts +0 -332
  205. package/tests/expr/date.spec.ts +0 -459
  206. package/tests/expr/math.expected.ts +0 -62
  207. package/tests/expr/math.spec.ts +0 -59
  208. package/tests/expr/string.expected.ts +0 -218
  209. package/tests/expr/string.spec.ts +0 -300
  210. package/tests/expr/utility.expected.ts +0 -147
  211. package/tests/expr/utility.spec.ts +0 -155
  212. package/tests/select/basic.expected.ts +0 -322
  213. package/tests/select/basic.spec.ts +0 -433
  214. package/tests/select/filter.expected.ts +0 -357
  215. package/tests/select/filter.spec.ts +0 -954
  216. package/tests/select/group.expected.ts +0 -169
  217. package/tests/select/group.spec.ts +0 -159
  218. package/tests/select/join.expected.ts +0 -582
  219. package/tests/select/join.spec.ts +0 -692
  220. package/tests/select/order.expected.ts +0 -150
  221. package/tests/select/order.spec.ts +0 -140
  222. package/tests/select/recursive-cte.expected.ts +0 -244
  223. package/tests/select/recursive-cte.spec.ts +0 -514
  224. package/tests/select/result-meta.spec.ts +0 -270
  225. package/tests/select/subquery.expected.ts +0 -363
  226. package/tests/select/subquery.spec.ts +0 -441
  227. package/tests/select/view.expected.ts +0 -155
  228. package/tests/select/view.spec.ts +0 -235
  229. package/tests/select/window.expected.ts +0 -345
  230. package/tests/select/window.spec.ts +0 -433
  231. package/tests/setup/MockExecutor.ts +0 -18
  232. package/tests/setup/TestDbContext.ts +0 -59
  233. package/tests/setup/models/Company.ts +0 -13
  234. package/tests/setup/models/Employee.ts +0 -10
  235. package/tests/setup/models/MonthlySales.ts +0 -11
  236. package/tests/setup/models/Post.ts +0 -16
  237. package/tests/setup/models/Sales.ts +0 -10
  238. package/tests/setup/models/User.ts +0 -19
  239. package/tests/setup/procedure/GetAllUsers.ts +0 -9
  240. package/tests/setup/procedure/GetUserById.ts +0 -12
  241. package/tests/setup/test-utils.ts +0 -72
  242. package/tests/setup/views/ActiveUsers.ts +0 -8
  243. package/tests/setup/views/UserSummary.ts +0 -11
  244. package/tests/types/nullable-queryable-record.spec.ts +0 -97
  245. package/tests/utils/result-parser-perf.spec.ts +0 -143
  246. package/tests/utils/result-parser.spec.ts +0 -667
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  //#region ========== Core ==========
2
2
 
3
- // Functional API (recommended)
3
+ // 함수형 API (권장)
4
4
  export * from "./define-db-context";
5
5
  export * from "./create-db-context";
6
6
  export * from "./types/db-context-def";
@@ -25,12 +25,12 @@ export * from "./expr/expr-unit";
25
25
 
26
26
  //#region ========== Schema Builders ==========
27
27
 
28
- // Table / View / Procedure
28
+ // 테이블 / / 프로시저
29
29
  export * from "./schema/table-builder";
30
30
  export * from "./schema/view-builder";
31
31
  export * from "./schema/procedure-builder";
32
32
 
33
- // Factory
33
+ // 팩토리
34
34
  export * from "./schema/factory/column-builder";
35
35
  export * from "./schema/factory/index-builder";
36
36
  export * from "./schema/factory/relation-builder";
@@ -59,19 +59,19 @@ export * from "./query-builder/postgresql/postgresql-expr-renderer";
59
59
 
60
60
  //#region ========== Types ==========
61
61
 
62
- // Database types
62
+ // 데이터베이스 타입
63
63
  export * from "./types/db";
64
64
 
65
- // Result parsing
65
+ // 결과 파싱
66
66
  export * from "./utils/result-parser";
67
67
 
68
- // Column types
68
+ // column 타입
69
69
  export * from "./types/column";
70
70
 
71
- // Expression types
71
+ // 표현식 타입
72
72
  export * from "./types/expr";
73
73
 
74
- // QueryDef types
74
+ // QueryDef 타입
75
75
  export * from "./types/query-def";
76
76
 
77
77
  //#endregion
@@ -4,5 +4,5 @@ export const _Migration = Table("_migration")
4
4
  .columns((c) => ({
5
5
  code: c.varchar(255),
6
6
  }))
7
- .description("System Migration Table")
7
+ .description("시스템 마이그레이션 테이블")
8
8
  .primaryKey("code");
@@ -68,12 +68,12 @@ import type {
68
68
  import type { SelectQueryDef } from "../../types/query-def";
69
69
 
70
70
  /**
71
- * Expr → SQL Render abstract base class
71
+ * Expr → SQL 렌더링 추상 기본 클래스
72
72
  *
73
- * Base principles:
74
- * - Implement only 100% identical logic across all dialects (dispatch)
75
- * - If different at all, make it abstract
76
- * - Method names match expr.type (enables dynamic dispatch)
73
+ * 기본 원칙:
74
+ * - 모든 dialect에서 100% 동일한 로직만 구현 (dispatch)
75
+ * - 조금이라도 다르면 abstract로 처리
76
+ * - 메서드 이름이 expr.type 동일 (동적 dispatch 가능)
77
77
  */
78
78
  export abstract class ExprRendererBase {
79
79
  constructor(protected buildSelect: (def: SelectQueryDef) => string) {}
@@ -81,31 +81,31 @@ export abstract class ExprRendererBase {
81
81
  //#region ========== Public Utilities ==========
82
82
 
83
83
  /**
84
- * Wrap identifier (table name, column name, etc.)
84
+ * 식별자 감싸기 (테이블명, column )
85
85
  * MySQL: `name`, MSSQL: [name], PostgreSQL: "name"
86
86
  */
87
87
  abstract wrap(name: string): string;
88
88
 
89
89
  /**
90
- * Escape for SQL string literals
91
- * Called when used as a string value in dynamic SQL or system queries
92
- * e.g.: WHERE schema_name = 'escaped_value'
90
+ * SQL 문자열 리터럴용 이스케이프
91
+ * 동적 SQL이나 시스템 쿼리에서 문자열 값으로 사용할 호출
92
+ * 예: WHERE schema_name = 'escaped_value'
93
93
  */
94
94
  abstract escapeString(value: string): string;
95
95
 
96
96
  /**
97
- * Value escape (transform to appropriate SQL literal based on type)
97
+ * 이스케이프 (타입에 맞는 SQL 리터럴로 변환)
98
98
  */
99
99
  abstract escapeValue(value: unknown): string;
100
100
 
101
101
  //#endregion
102
102
 
103
- //#region ========== Dispatch (100% identical) ==========
103
+ //#region ========== Dispatch (100% 동일) ==========
104
104
 
105
105
  render(expr: Expr | WhereExpr): string {
106
106
  const method = this[expr.type as keyof this];
107
107
  if (typeof method !== "function") {
108
- throw new Error(`Unknown Expr type: ${expr.type}`);
108
+ throw new Error(`알 수 없는 Expr 타입: ${expr.type}`);
109
109
  }
110
110
  return (method as (e: Expr | WhereExpr) => string).call(this, expr);
111
111
  }
@@ -125,7 +125,7 @@ export abstract class ExprRendererBase {
125
125
 
126
126
  //#endregion
127
127
 
128
- //#region ========== Abstract - comparison (null-safe required) ==========
128
+ //#region ========== Abstract - 비교 (null-safe 필수) ==========
129
129
 
130
130
  protected abstract eq(expr: ExprEq): string;
131
131
  protected abstract gt(expr: ExprGt): string;
@@ -142,7 +142,7 @@ export abstract class ExprRendererBase {
142
142
 
143
143
  //#endregion
144
144
 
145
- //#region ========== Abstract - logic ==========
145
+ //#region ========== Abstract - 논리 ==========
146
146
 
147
147
  protected abstract not(expr: ExprNot): string;
148
148
  protected abstract and(expr: ExprAnd): string;
@@ -150,7 +150,7 @@ export abstract class ExprRendererBase {
150
150
 
151
151
  //#endregion
152
152
 
153
- //#region ========== Abstract - String (null processing required) ==========
153
+ //#region ========== Abstract - 문자열 (null 처리 필수) ==========
154
154
 
155
155
  protected abstract concat(expr: ExprConcat): string;
156
156
  protected abstract left(expr: ExprLeft): string;
@@ -167,7 +167,7 @@ export abstract class ExprRendererBase {
167
167
 
168
168
  //#endregion
169
169
 
170
- //#region ========== Abstract - Number ==========
170
+ //#region ========== Abstract - 숫자 ==========
171
171
 
172
172
  protected abstract abs(expr: ExprAbs): string;
173
173
  protected abstract round(expr: ExprRound): string;
@@ -176,7 +176,7 @@ export abstract class ExprRendererBase {
176
176
 
177
177
  //#endregion
178
178
 
179
- //#region ========== Abstract - Date ==========
179
+ //#region ========== Abstract - 날짜 ==========
180
180
 
181
181
  protected abstract year(expr: ExprYear): string;
182
182
  protected abstract month(expr: ExprMonth): string;
@@ -193,7 +193,7 @@ export abstract class ExprRendererBase {
193
193
 
194
194
  //#endregion
195
195
 
196
- //#region ========== Abstract - Condition ==========
196
+ //#region ========== Abstract - 조건 ==========
197
197
 
198
198
  protected abstract coalesce(expr: ExprCoalesce): string;
199
199
  protected abstract nullIf(expr: ExprNullIf): string;
@@ -203,7 +203,7 @@ export abstract class ExprRendererBase {
203
203
 
204
204
  //#endregion
205
205
 
206
- //#region ========== Abstract - Aggregate ==========
206
+ //#region ========== Abstract - 집계 ==========
207
207
 
208
208
  protected abstract count(expr: ExprCount): string;
209
209
  protected abstract sum(expr: ExprSum): string;
@@ -213,7 +213,7 @@ export abstract class ExprRendererBase {
213
213
 
214
214
  //#endregion
215
215
 
216
- //#region ========== Abstract - Other ==========
216
+ //#region ========== Abstract - 기타 ==========
217
217
 
218
218
  protected abstract greatest(expr: ExprGreatest): string;
219
219
  protected abstract least(expr: ExprLeast): string;
@@ -229,7 +229,7 @@ export abstract class ExprRendererBase {
229
229
 
230
230
  //#endregion
231
231
 
232
- //#region ========== Abstract - System ==========
232
+ //#region ========== Abstract - 시스템 ==========
233
233
 
234
234
  protected abstract subquery(expr: ExprSubquery): string;
235
235
 
@@ -37,14 +37,14 @@ import type { QueryBuildResult } from "../../types/db";
37
37
  import type { ExprRendererBase } from "./expr-renderer-base";
38
38
 
39
39
  /**
40
- * QueryDef → SQL render abstract base class
40
+ * QueryDef → SQL 렌더링 추상 기본 클래스
41
41
  *
42
- * Base principles:
43
- * - Implement only 100% identical logic across all dialects (dispatch)
44
- * - If different at all, make it abstract
45
- * - Method name identical to def.type (enables dynamic dispatch)
42
+ * 기본 원칙:
43
+ * - 모든 dialect에서 100% 동일한 로직만 구현 (dispatch)
44
+ * - 조금이라도 다르면 abstract로 처리
45
+ * - 메서드 이름이 def.type 동일 (동적 dispatch 가능)
46
46
  */
47
- /** Properties that are part of a basic (non-LATERAL) JOIN */
47
+ /** 기본(비 LATERAL) JOIN 속성 목록 */
48
48
  const BASIC_JOIN_PROPS: ReadonlySet<string> = new Set<
49
49
  keyof Pick<SelectQueryDefJoin, "type" | "from" | "as" | "where" | "isSingle">
50
50
  >(["type", "from", "as", "where", "isSingle"]);
@@ -52,35 +52,35 @@ const BASIC_JOIN_PROPS: ReadonlySet<string> = new Set<
52
52
  export abstract class QueryBuilderBase {
53
53
  protected abstract expr: ExprRendererBase;
54
54
 
55
- //#region ========== Dispatch (100% identical) ==========
55
+ //#region ========== Dispatch (100% 동일) ==========
56
56
 
57
57
  build(def: QueryDef): QueryBuildResult {
58
58
  const method = this[def.type as keyof this];
59
59
  if (typeof method !== "function") {
60
- throw new Error(`Unknown QueryDef type: ${def.type}`);
60
+ throw new Error(`알 수 없는 QueryDef 타입: ${def.type}`);
61
61
  }
62
62
  return (method as (d: QueryDef) => QueryBuildResult).call(this, def);
63
63
  }
64
64
 
65
- /** Helper to wrap SQL in QueryBuildResult */
65
+ /** SQL을 QueryBuildResult로 래핑하는 헬퍼 */
66
66
  protected result(sql: string, resultSetIndex?: number): QueryBuildResult {
67
67
  return resultSetIndex != null ? { sql, resultSetIndex } : { sql };
68
68
  }
69
69
 
70
70
  //#endregion
71
71
 
72
- //#region ========== Common render method (100% identical) ==========
72
+ //#region ========== 공통 렌더링 메서드 (100% 동일) ==========
73
73
 
74
- /** Table name render (different per dialect, so abstract) */
74
+ /** 테이블명 렌더링 (dialect마다 다르므로 abstract) */
75
75
  protected abstract tableName(obj: QueryDefObjectName): string;
76
76
 
77
- /** WHERE clause render */
77
+ /** WHERE 렌더링 */
78
78
  protected renderWhere(wheres: WhereExpr[] | undefined): string {
79
79
  if (wheres == null || wheres.length === 0) return "";
80
80
  return ` WHERE ${this.expr.renderWhere(wheres)}`;
81
81
  }
82
82
 
83
- /** ORDER BY clause render */
83
+ /** ORDER BY 렌더링 */
84
84
  protected renderOrderBy(orderBy: [Expr, ("ASC" | "DESC")?][] | undefined): string {
85
85
  if (orderBy == null || orderBy.length === 0) return "";
86
86
  const parts = orderBy.map(
@@ -89,58 +89,58 @@ export abstract class QueryBuilderBase {
89
89
  return ` ORDER BY ${parts.join(", ")}`;
90
90
  }
91
91
 
92
- /** GROUP BY clause render */
92
+ /** GROUP BY 렌더링 */
93
93
  protected renderGroupBy(groupBy: Expr[] | undefined): string {
94
94
  if (groupBy == null || groupBy.length === 0) return "";
95
95
  return ` GROUP BY ${groupBy.map((g) => this.expr.render(g)).join(", ")}`;
96
96
  }
97
97
 
98
- /** HAVING clause render */
98
+ /** HAVING 렌더링 */
99
99
  protected renderHaving(having: WhereExpr[] | undefined): string {
100
100
  if (having == null || having.length === 0) return "";
101
101
  return ` HAVING ${this.expr.renderWhere(having)}`;
102
102
  }
103
103
 
104
- /** JOIN clause render */
104
+ /** JOIN 렌더링 */
105
105
  protected renderJoins(joins: SelectQueryDefJoin[] | undefined): string {
106
106
  if (joins == null || joins.length === 0) return "";
107
107
  return joins.map((j) => this.renderJoin(j)).join("");
108
108
  }
109
109
 
110
- /** Single JOIN render (different per dialect, so abstract) */
110
+ /** 단일 JOIN 렌더링 (dialect마다 다르므로 abstract) */
111
111
  protected abstract renderJoin(join: SelectQueryDefJoin): string;
112
112
 
113
113
  /**
114
- * Detect if JOIN needs LATERAL/CROSS APPLY
114
+ * JOIN LATERAL/CROSS APPLY가 필요한지 감지
115
115
  *
116
- * If JOIN has only basic properties (type, from, as, where, isSingle), treat as normal JOIN.
117
- * Otherwise, subquery is needed, so use LATERAL JOIN:
116
+ * JOIN 기본 속성(type, from, as, where, isSingle) 가지면 일반 JOIN으로 처리.
117
+ * 외의 경우 서브쿼리가 필요하므로 LATERAL JOIN 사용:
118
118
  *
119
- * - select: column transformation/aggregation needed (normal JOIN references entire table)
120
- * - joins: nested JOIN handled inside subquery
121
- * - orderBy, top, limit: sorting/limit applied inside subquery
122
- * - groupBy, having: aggregation performed inside subquery
123
- * - distinct: deduplication applied inside subquery
124
- * - from (array): UNION ALL pattern
119
+ * - select: column 변환/집계가 필요 (일반 JOIN 전체 테이블 참조)
120
+ * - joins: 중첩 JOIN 서브쿼리 내부에서 처리
121
+ * - orderBy, top, limit: 정렬/제한은 서브쿼리 내부에서 적용
122
+ * - groupBy, having: 집계는 서브쿼리 내부에서 수행
123
+ * - distinct: 중복 제거는 서브쿼리 내부에서 적용
124
+ * - from (array): UNION ALL 패턴
125
125
  *
126
- * Note: select and joins are auto-generated during nested joins, so not in basicJoinProps.
127
- * Even if user doesn't call .select() directly, internal .joinSingle() may add
128
- * select/joins, which also requires subquery.
126
+ * 참고: select joins 중첩 join 자동 생성되므로 basicJoinProps에 없음.
127
+ * 사용자가 직접 .select() 호출하지 않더라도 내부 .joinSingle()
128
+ * select/joins 추가할 있으며, 이 경우에도 서브쿼리가 필요함.
129
129
  */
130
130
  protected needsLateral(join: SelectQueryDefJoin): boolean {
131
- // If from is array, always LATERAL (UNION ALL pattern)
131
+ // from 배열이면 항상 LATERAL (UNION ALL 패턴)
132
132
  if (Array.isArray(join.from)) {
133
133
  return true;
134
134
  }
135
135
 
136
- // LATERAL needed if join has additional properties beyond basic JOIN properties
136
+ // 기본 JOIN 속성 추가 속성이 있으면 LATERAL 필요
137
137
  return Object.keys(join).some((key) => !BASIC_JOIN_PROPS.has(key));
138
138
  }
139
139
 
140
- /** FROM clause source render */
140
+ /** FROM 소스 렌더링 */
141
141
  protected renderFrom(from: SelectQueryDef["from"]): string {
142
142
  if (from == null) {
143
- throw new Error("FROM clause is required.");
143
+ throw new Error("FROM 절이 필요합니다.");
144
144
  }
145
145
  if (typeof from === "string") {
146
146
  return this.expr.wrap(from);
@@ -69,22 +69,22 @@ import type { DataType } from "../../types/column";
69
69
  import { ExprRendererBase } from "../base/expr-renderer-base";
70
70
 
71
71
  /**
72
- * MSSQL expression renderer
72
+ * MSSQL 표현식 렌더러
73
73
  */
74
74
  export class MssqlExprRenderer extends ExprRendererBase {
75
- //#region ========== Utilities (public - also used by QueryBuilder) ==========
75
+ //#region ========== 유틸리티 (public - QueryBuilder에서도 사용) ==========
76
76
 
77
- /** Wrap identifier */
77
+ /** 식별자 감싸기 */
78
78
  wrap(name: string): string {
79
79
  return `[${name.replace(/]/g, "]]")}]`;
80
80
  }
81
81
 
82
- /** Escape for SQL string literals (returns without quotes) */
82
+ /** SQL 문자열 리터럴용 이스케이프 (따옴표 제외) */
83
83
  escapeString(value: string): string {
84
84
  return value.replace(/'/g, "''");
85
85
  }
86
86
 
87
- /** Value escape */
87
+ /** 이스케이프 */
88
88
  escapeValue(value: unknown): string {
89
89
  if (value == null) {
90
90
  return "NULL";
@@ -113,10 +113,10 @@ export class MssqlExprRenderer extends ExprRendererBase {
113
113
  if (value instanceof Uint8Array) {
114
114
  return `0x${bytes.toHex(value)}`;
115
115
  }
116
- throw new Error(`Unknown value type: ${typeof value}`);
116
+ throw new Error(`알 없는 값 타입: ${typeof value}`);
117
117
  }
118
118
 
119
- /** DataType → SQL type */
119
+ /** DataType → SQL 타입 변환 */
120
120
  renderDataType(dataType: DataType): string {
121
121
  switch (dataType.type) {
122
122
  case "int":
@@ -176,7 +176,7 @@ export class MssqlExprRenderer extends ExprRendererBase {
176
176
  //#region ========== comparison (null-safe) ==========
177
177
 
178
178
  protected eq(expr: ExprEq): string {
179
- // MSSQL: null-safe equal (OR Pattern)
179
+ // MSSQL: NULL 안전 동등 비교 (OR 패턴)
180
180
  const left = this.render(expr.source);
181
181
  const right = this.render(expr.target);
182
182
  return `((${left} IS NULL AND ${right} IS NULL) OR ${left} = ${right})`;
@@ -217,18 +217,18 @@ export class MssqlExprRenderer extends ExprRendererBase {
217
217
  }
218
218
 
219
219
  protected like(expr: ExprLike): string {
220
- // Always add ESCAPE '\'
220
+ // 항상 ESCAPE '\' 추가
221
221
  return `${this.render(expr.source)} LIKE ${this.render(expr.pattern)} ESCAPE '\\'`;
222
222
  }
223
223
 
224
224
  protected regexp(_expr: ExprRegexp): string {
225
- // MSSQL does not support REGEXP - needs LIKE pattern or CLR
226
- throw new Error("MSSQL does not natively support REGEXP.");
225
+ // MSSQL REGEXP을 지원하지 않음 - LIKE 패턴 또는 CLR 필요
226
+ throw new Error("MSSQL 기본적으로 REGEXP을 지원하지 않습니다.");
227
227
  }
228
228
 
229
229
  protected in(expr: ExprIn): string {
230
230
  if (expr.values.length === 0) {
231
- return "1=0"; // empty IN is always false
231
+ return "1=0"; // IN 항상 false
232
232
  }
233
233
  const values = expr.values.map((v) => this.render(v)).join(", ");
234
234
  return `${this.render(expr.source)} IN (${values})`;
@@ -239,7 +239,7 @@ export class MssqlExprRenderer extends ExprRendererBase {
239
239
  }
240
240
 
241
241
  protected exists(expr: ExprExists): string {
242
- // Render as SELECT 1
242
+ // SELECT 1로 렌더링
243
243
  const subquery = this.buildSelect({
244
244
  ...expr.query,
245
245
  select: { _: { type: "value", value: 1 } },
@@ -270,7 +270,7 @@ export class MssqlExprRenderer extends ExprRendererBase {
270
270
  //#region ========== String (null handling) ==========
271
271
 
272
272
  protected concat(expr: ExprConcat): string {
273
- // MSSQL 2012+: CONCAT function automatically treats NULL as empty string
273
+ // MSSQL 2012+: CONCAT 함수는 NULL을 자동으로 문자열로 처리
274
274
  const args = expr.args.map((a) => this.render(a)).join(", ");
275
275
  return `CONCAT(${args})`;
276
276
  }
@@ -288,7 +288,7 @@ export class MssqlExprRenderer extends ExprRendererBase {
288
288
  }
289
289
 
290
290
  protected padStart(expr: ExprPadStart): string {
291
- // MSSQL: RIGHT(REPLICATE(fill, len) + source, len)
291
+ // MSSQL: RIGHT(REPLICATE(채움문자, 길이) + 원본, 길이)
292
292
  const source = this.render(expr.source);
293
293
  const len = this.render(expr.length);
294
294
  const fill = this.render(expr.fillString);
@@ -308,12 +308,12 @@ export class MssqlExprRenderer extends ExprRendererBase {
308
308
  }
309
309
 
310
310
  protected length(expr: ExprLength): string {
311
- // MSSQL: LEN() (null handling)
311
+ // MSSQL: LEN() (null 처리)
312
312
  return `LEN(ISNULL(${this.render(expr.arg)}, N''))`;
313
313
  }
314
314
 
315
315
  protected byteLength(expr: ExprByteLength): string {
316
- // MSSQL: DATALENGTH() (null handling)
316
+ // MSSQL: DATALENGTH() (null 처리)
317
317
  return `DATALENGTH(ISNULL(${this.render(expr.arg)}, N''))`;
318
318
  }
319
319
 
@@ -321,7 +321,7 @@ export class MssqlExprRenderer extends ExprRendererBase {
321
321
  if (expr.length != null) {
322
322
  return `SUBSTRING(${this.render(expr.source)}, ${this.render(expr.start)}, ${this.render(expr.length)})`;
323
323
  }
324
- // MSSQL: if no length, go to end
324
+ // MSSQL: 길이 미지정 끝까지
325
325
  return `SUBSTRING(${this.render(expr.source)}, ${this.render(expr.start)}, LEN(${this.render(expr.source)}))`;
326
326
  }
327
327
 
@@ -384,9 +384,9 @@ export class MssqlExprRenderer extends ExprRendererBase {
384
384
 
385
385
  protected isoWeekStartDate(expr: ExprIsoWeekStartDate): string {
386
386
  const src = this.render(expr.arg);
387
- // ISO week start date (Monday) - always returns Monday regardless of @@DATEFIRST
388
- // Principle: DATEDIFF(DAY, 0, date) is the number of days from 1900-01-01 (Monday)
389
- // (days + 6) % 7 + 1 = 1(Mon), 2(Tue), ..., 7(Sun)
387
+ // ISO 시작일 (월요일) - @@DATEFIRST와 무관하게 항상 월요일 반환
388
+ // 원리: DATEDIFF(DAY, 0, date) 1900-01-01(월요일)부터의 일수
389
+ // (days + 6) % 7 + 1 = 1(), 2(), ..., 7()
390
390
  const weekDay = `((DATEDIFF(DAY, 0, ${src}) + 6) % 7 + 1)`;
391
391
  return `DATEADD(DAY, 1 - ${weekDay}, CAST(${src} AS DATE))`;
392
392
  }
@@ -411,7 +411,7 @@ export class MssqlExprRenderer extends ExprRendererBase {
411
411
  }
412
412
 
413
413
  protected formatDate(expr: ExprFormatDate): string {
414
- // JS format → MSSQL FORMAT style
414
+ // JS 포맷 → MSSQL FORMAT 스타일
415
415
  const mssqlFormat = this.convertDateFormat(expr.format);
416
416
  return `FORMAT(${this.render(expr.source)}, '${mssqlFormat}')`;
417
417
  }
@@ -434,7 +434,7 @@ export class MssqlExprRenderer extends ExprRendererBase {
434
434
  }
435
435
 
436
436
  private convertDateFormat(format: string): string {
437
- // For MSSQL FORMAT function (uses the same format)
437
+ // MSSQL FORMAT 함수용 (동일 포맷 사용)
438
438
  return format;
439
439
  }
440
440
 
@@ -502,17 +502,17 @@ export class MssqlExprRenderer extends ExprRendererBase {
502
502
  //#region ========== Other ==========
503
503
 
504
504
  protected greatest(expr: ExprGreatest): string {
505
- if (expr.args.length === 0) throw new Error("greatest requires at least one argument.");
505
+ if (expr.args.length === 0) throw new Error("greatest에는 최소 1개의 인수가 필요합니다.");
506
506
  if (expr.args.length === 1) return this.render(expr.args[0]);
507
- // MSSQL 2012+: VALUES + MAX approach
507
+ // MSSQL 2012+: VALUES + MAX 방식
508
508
  const values = expr.args.map((a) => `(${this.render(a)})`).join(", ");
509
509
  return `(SELECT MAX(v) FROM (VALUES ${values}) AS t(v))`;
510
510
  }
511
511
 
512
512
  protected least(expr: ExprLeast): string {
513
- if (expr.args.length === 0) throw new Error("least requires at least one argument.");
513
+ if (expr.args.length === 0) throw new Error("least에는 최소 1개의 인수가 필요합니다.");
514
514
  if (expr.args.length === 1) return this.render(expr.args[0]);
515
- // MSSQL 2012+: VALUES + MIN approach
515
+ // MSSQL 2012+: VALUES + MIN 방식
516
516
  const values = expr.args.map((a) => `(${this.render(a)})`).join(", ");
517
517
  return `(SELECT MIN(v) FROM (VALUES ${values}) AS t(v))`;
518
518
  }
@@ -537,7 +537,7 @@ export class MssqlExprRenderer extends ExprRendererBase {
537
537
  const fn = this.renderWindowFn(expr.fn);
538
538
  let over = this.renderWindowSpec(expr.spec);
539
539
 
540
- // LAST_VALUE default frame only sees up to CURRENT ROW, so full frame must be specified
540
+ // LAST_VALUE 기본 프레임은 CURRENT ROW까지만 보므로 전체 프레임을 지정해야
541
541
  if (expr.fn.type === "lastValue" && over.length > 0) {
542
542
  over += " ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING";
543
543
  }