sonamu 0.5.6 → 0.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/decorators.d.ts +1 -0
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +1 -1
- package/dist/api/decorators.js.map +1 -1
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +1 -1
- package/dist/api/sonamu.js.map +1 -1
- package/dist/database/db.d.ts +3 -0
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +1 -1
- package/dist/database/db.js.map +1 -1
- package/dist/database/puri-wrapper.d.ts +22 -10
- package/dist/database/puri-wrapper.d.ts.map +1 -1
- package/dist/database/puri-wrapper.js +1 -1
- package/dist/database/puri-wrapper.js.map +1 -1
- package/dist/database/puri.d.ts +91 -66
- package/dist/database/puri.d.ts.map +1 -1
- package/dist/database/puri.js +1 -1
- package/dist/database/puri.js.map +1 -1
- package/dist/database/puri.types.d.ts +28 -42
- package/dist/database/puri.types.d.ts.map +1 -1
- package/dist/database/transaction-context.d.ts +3 -3
- package/dist/database/transaction-context.d.ts.map +1 -1
- package/dist/database/transaction-context.js.map +1 -1
- package/dist/templates/service.template.d.ts.map +1 -1
- package/dist/templates/service.template.js +1 -1
- package/dist/templates/service.template.js.map +1 -1
- package/dist/types/types.d.ts +1 -1
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js.map +1 -1
- package/package.json +1 -2
- package/src/api/decorators.ts +14 -5
- package/src/api/sonamu.ts +21 -20
- package/src/database/db.ts +44 -9
- package/src/database/puri-wrapper.ts +104 -26
- package/src/database/puri.ts +429 -557
- package/src/database/puri.types.ts +99 -202
- package/src/database/transaction-context.ts +4 -4
- package/src/templates/service.template.ts +10 -1
- package/src/types/types.ts +1 -1
|
@@ -5,8 +5,8 @@ import { DatabaseSchemaExtend } from "../types/types";
|
|
|
5
5
|
import chalk from "chalk";
|
|
6
6
|
import { DBPreset } from "./db";
|
|
7
7
|
|
|
8
|
-
type TableName<
|
|
9
|
-
keyof
|
|
8
|
+
type TableName<TSchema extends DatabaseSchemaExtend> = Extract<
|
|
9
|
+
keyof TSchema,
|
|
10
10
|
string
|
|
11
11
|
>;
|
|
12
12
|
|
|
@@ -17,7 +17,7 @@ export type TransactionalOptions = {
|
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
export class PuriWrapper<
|
|
20
|
-
|
|
20
|
+
TSchema extends DatabaseSchemaExtend = DatabaseSchemaExtend,
|
|
21
21
|
> {
|
|
22
22
|
constructor(
|
|
23
23
|
public knex: Knex,
|
|
@@ -27,60 +27,138 @@ export class PuriWrapper<
|
|
|
27
27
|
raw(sql: string): Knex.Raw {
|
|
28
28
|
return this.knex.raw(sql);
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
|
|
31
|
+
// 테이블명으로 시작
|
|
32
|
+
from<TTable extends keyof TSchema>(
|
|
32
33
|
tableName: TTable
|
|
33
|
-
): Puri<
|
|
34
|
-
|
|
34
|
+
): Puri<
|
|
35
|
+
TSchema,
|
|
36
|
+
Record<TTable, TSchema[TTable]>,
|
|
37
|
+
Omit<TSchema[TTable], "__fulltext__">
|
|
38
|
+
>;
|
|
39
|
+
// 테이블명 + Alias로 시작
|
|
40
|
+
from<TTable extends keyof TSchema, TAlias extends string>(spec: {
|
|
41
|
+
[K in TAlias]: TTable;
|
|
42
|
+
}): Puri<
|
|
43
|
+
TSchema,
|
|
44
|
+
Record<TAlias, TSchema[TTable]>,
|
|
45
|
+
Omit<TSchema[TTable], "__fulltext__">
|
|
46
|
+
>;
|
|
47
|
+
// 서브쿼리로 시작
|
|
48
|
+
from<TAlias extends string, TSubResult>(spec: {
|
|
49
|
+
[K in TAlias]: Puri<TSchema, any, TSubResult>;
|
|
50
|
+
}): Puri<
|
|
51
|
+
TSchema,
|
|
52
|
+
Record<TAlias, TSubResult>,
|
|
53
|
+
Omit<TSubResult, "__fulltext__">
|
|
54
|
+
>;
|
|
55
|
+
from(spec: any): any {
|
|
56
|
+
return new Puri(this.knex, spec);
|
|
35
57
|
}
|
|
36
58
|
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
59
|
+
// 테이블명으로 시작
|
|
60
|
+
table<TTable extends keyof TSchema>(
|
|
61
|
+
tableName: TTable
|
|
62
|
+
): Puri<
|
|
63
|
+
TSchema,
|
|
64
|
+
Record<TTable, TSchema[TTable]>,
|
|
65
|
+
Omit<TSchema[TTable], "__fulltext__">
|
|
66
|
+
>;
|
|
67
|
+
// 테이블명 + Alias로 시작
|
|
68
|
+
table<TTable extends keyof TSchema, TAlias extends string>(spec: {
|
|
69
|
+
[K in TAlias]: TTable;
|
|
70
|
+
}): Puri<
|
|
71
|
+
TSchema,
|
|
72
|
+
Record<TAlias, TSchema[TTable]>,
|
|
73
|
+
Omit<TSchema[TTable], "__fulltext__">
|
|
74
|
+
>;
|
|
75
|
+
// 서브쿼리로 시작
|
|
76
|
+
table<TAlias extends string, TSubResult>(spec: {
|
|
77
|
+
[K in TAlias]: Puri<TSchema, any, TSubResult>;
|
|
78
|
+
}): Puri<
|
|
79
|
+
TSchema,
|
|
80
|
+
Record<TAlias, TSubResult>,
|
|
81
|
+
Omit<TSubResult, "__fulltext__">
|
|
82
|
+
>;
|
|
83
|
+
table(spec: any): any {
|
|
84
|
+
return new Puri(this.knex, spec);
|
|
43
85
|
}
|
|
44
86
|
|
|
45
87
|
async transaction<T>(
|
|
46
88
|
callback: (trx: PuriTransactionWrapper) => Promise<T>,
|
|
47
89
|
options: TransactionalOptions = {}
|
|
48
90
|
): Promise<T> {
|
|
49
|
-
const { isolation, readOnly } = options;
|
|
91
|
+
const { isolation, readOnly, dbPreset = "w" } = options;
|
|
92
|
+
|
|
93
|
+
// @transactional 데코레이터와 동일한 로직: 이미 트랜잭션 컨텍스트가 있는지 확인
|
|
94
|
+
const { DB } = await import("./db");
|
|
95
|
+
const existingContext = DB.transactionStorage.getStore();
|
|
96
|
+
|
|
97
|
+
// AsyncLocalStorage 컨텍스트가 없거나 해당 preset의 트랜잭션이 없으면 새로 시작
|
|
98
|
+
const startTransaction = async (
|
|
99
|
+
knex: Knex | Knex.Transaction,
|
|
100
|
+
upsertBuilder: UpsertBuilder
|
|
101
|
+
) => {
|
|
102
|
+
return knex.transaction(
|
|
103
|
+
async (trx) => {
|
|
104
|
+
const trxWrapper = new PuriTransactionWrapper(trx, upsertBuilder);
|
|
105
|
+
|
|
106
|
+
// TransactionContext에 트랜잭션 저장
|
|
107
|
+
DB.getTransactionContext().setTransaction(dbPreset, trxWrapper);
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
return await callback(trxWrapper);
|
|
111
|
+
} finally {
|
|
112
|
+
// 트랜잭션 제거
|
|
113
|
+
DB.getTransactionContext().deleteTransaction(dbPreset);
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
{ isolationLevel: isolation, readOnly }
|
|
117
|
+
);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// AsyncLocalStorage 컨텍스트가 없으면 새로 생성
|
|
121
|
+
if (!existingContext) {
|
|
122
|
+
return DB.runWithTransaction(() =>
|
|
123
|
+
startTransaction(this.knex, this.upsertBuilder)
|
|
124
|
+
);
|
|
125
|
+
}
|
|
50
126
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
127
|
+
// 해당 preset의 트랜잭션이 이미 있으면 SAVEPOINT로 중첩 트랜잭션 생성
|
|
128
|
+
const existingTrx = existingContext.getTransaction(dbPreset);
|
|
129
|
+
if (existingTrx) {
|
|
130
|
+
return startTransaction(existingTrx.trx, existingTrx.upsertBuilder);
|
|
131
|
+
} else {
|
|
132
|
+
// 컨텍스트는 있지만 이 preset의 트랜잭션은 없는 경우 (같은 컨텍스트 내에서 실행)
|
|
133
|
+
return startTransaction(this.knex, this.upsertBuilder);
|
|
134
|
+
}
|
|
57
135
|
}
|
|
58
136
|
|
|
59
|
-
ubRegister<TTable extends TableName<
|
|
137
|
+
ubRegister<TTable extends TableName<TSchema>>(
|
|
60
138
|
tableName: TTable,
|
|
61
139
|
row: Partial<{
|
|
62
|
-
[K in keyof
|
|
140
|
+
[K in keyof TSchema[TTable]]: TSchema[TTable][K] | UBRef;
|
|
63
141
|
}>
|
|
64
142
|
): UBRef {
|
|
65
143
|
return this.upsertBuilder.register(tableName, row);
|
|
66
144
|
}
|
|
67
145
|
|
|
68
146
|
ubUpsert(
|
|
69
|
-
tableName: TableName<
|
|
147
|
+
tableName: TableName<TSchema>,
|
|
70
148
|
chunkSize?: number
|
|
71
149
|
): Promise<number[]> {
|
|
72
150
|
return this.upsertBuilder.upsert(this.knex, tableName, chunkSize);
|
|
73
151
|
}
|
|
74
152
|
|
|
75
153
|
ubInsertOnly(
|
|
76
|
-
tableName: TableName<
|
|
154
|
+
tableName: TableName<TSchema>,
|
|
77
155
|
chunkSize?: number
|
|
78
156
|
): Promise<number[]> {
|
|
79
157
|
return this.upsertBuilder.insertOnly(this.knex, tableName, chunkSize);
|
|
80
158
|
}
|
|
81
159
|
|
|
82
160
|
ubUpsertOrInsert(
|
|
83
|
-
tableName: TableName<
|
|
161
|
+
tableName: TableName<TSchema>,
|
|
84
162
|
mode: "upsert" | "insert",
|
|
85
163
|
chunkSize?: number
|
|
86
164
|
): Promise<number[]> {
|
|
@@ -93,7 +171,7 @@ export class PuriWrapper<
|
|
|
93
171
|
}
|
|
94
172
|
|
|
95
173
|
ubUpdateBatch(
|
|
96
|
-
tableName: TableName<
|
|
174
|
+
tableName: TableName<TSchema>,
|
|
97
175
|
options?: { chunkSize?: number; where?: string | string[] }
|
|
98
176
|
): Promise<void> {
|
|
99
177
|
return this.upsertBuilder.updateBatch(this.knex, tableName, options);
|