sonamu 0.2.4 → 0.2.6

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.
@@ -214,6 +214,8 @@ export class BaseModelClass {
214
214
  }> {
215
215
  const db = this.getDB(subset.startsWith("A") ? "w" : "r");
216
216
  baseTable = baseTable ?? pluralize(underscore(this.modelName));
217
+ const queryMode =
218
+ params.queryMode ?? (params.id !== undefined ? "list" : "both");
217
219
 
218
220
  const { select, virtual, joins, loaders } = subsetQuery;
219
221
  const qb = build({
@@ -239,55 +241,55 @@ export class BaseModelClass {
239
241
  }
240
242
  });
241
243
 
242
- // count
243
- let countQuery;
244
- if (params.id === undefined && params.withoutCount !== true) {
245
- const clonedQb = qb.clone().clear("order");
246
- const [, matched] =
247
- clonedQb
248
- .toQuery()
249
- .toLowerCase()
250
- .match(/select (distinct .+) from/) ?? [];
251
- if (matched) {
252
- countQuery = clonedQb
253
- .clear("select")
254
- .select(db.raw(`COUNT(${matched}) as total`));
255
- } else {
256
- countQuery = clonedQb.clear("select").count("*", { as: "total" });
244
+ // listQuery
245
+ const rows = await (async () => {
246
+ if (queryMode === "count") {
247
+ return [];
257
248
  }
258
- }
259
249
 
260
- // limit, offset
261
- if (params.num !== 0) {
262
- qb.limit(params.num!);
263
- qb.offset(params.num! * (params.page! - 1));
264
- }
250
+ // limit, offset
251
+ if (params.num !== 0) {
252
+ qb.limit(params.num!);
253
+ qb.offset(params.num! * (params.page! - 1));
254
+ }
265
255
 
266
- // select, rows
267
- qb.select(select);
268
- const listQuery = qb.clone();
256
+ // select, rows
257
+ const listQuery = qb.clone().select(select);
269
258
 
270
- // debug: listQuery
271
- if (debug === true || debug === "list") {
272
- console.debug(
273
- "DEBUG: list query",
274
- chalk.blue(listQuery.toQuery().toString())
275
- );
276
- }
259
+ let rows = await listQuery;
260
+ // debug: listQuery
261
+ if (debug === true || debug === "list") {
262
+ console.debug(
263
+ "DEBUG: list query",
264
+ chalk.blue(listQuery.toQuery().toString())
265
+ );
266
+ }
277
267
 
278
- // listQuery
279
- let rows = await listQuery;
280
- rows = await this.useLoaders(db, rows, loaders);
281
- rows = this.hydrate(rows);
268
+ rows = await this.useLoaders(db, rows, loaders);
269
+ rows = this.hydrate(rows);
270
+ return rows;
271
+ })();
282
272
 
283
273
  // countQuery
284
- let total = 0;
285
- if (countQuery) {
286
- const countResult = await countQuery;
287
- if (countResult && countResult[0] && countResult[0].total) {
288
- total = countResult[0].total;
274
+ const total = await (async () => {
275
+ if (queryMode === "list") {
276
+ return undefined;
289
277
  }
290
278
 
279
+ const clonedQb = qb.clone().clear("order");
280
+ const [, matched] =
281
+ clonedQb
282
+ .toQuery()
283
+ .toLowerCase()
284
+ .match(/select (distinct .+) from/) ?? [];
285
+ const countQuery = matched
286
+ ? clonedQb
287
+ .clear("select")
288
+ .select(db.raw(`COUNT(${matched}) as total`))
289
+ .first()
290
+ : clonedQb.clear("select").count("*", { as: "total" }).first();
291
+ const countRow: { total?: number } = await countQuery;
292
+
291
293
  // debug: countQuery
292
294
  if (debug === true || debug === "count") {
293
295
  console.debug(
@@ -295,7 +297,9 @@ export class BaseModelClass {
295
297
  chalk.blue(countQuery.toQuery().toString())
296
298
  );
297
299
  }
298
- }
300
+
301
+ return countRow?.total ?? 0;
302
+ })();
299
303
 
300
304
  return { rows, total, subsetQuery, qb };
301
305
  }
@@ -840,7 +840,7 @@ export class Migrator {
840
840
  ).map((f) => replaceNoActionOnMySQL(f));
841
841
 
842
842
  if (equal(entityForeigns, dbForeigns) === false) {
843
- console.dir({ entityForeigns, dbForeigns }, { depth: null });
843
+ // console.dir({ entityForeigns, dbForeigns }, { depth: null });
844
844
  return this.generateAlterCode_Foreigns(
845
845
  entitySet.table,
846
846
  entityForeigns,
@@ -1076,40 +1076,23 @@ export class Migrator {
1076
1076
  const foreignKeys = (matched ?? []).map((line: string) => {
1077
1077
  // 해당 라인을 정규식으로 파싱
1078
1078
  const matched = line.match(
1079
- /CONSTRAINT `(.+)` FOREIGN KEY \(`(.+)`\) REFERENCES `(.+)` \(`(.+)`\)( ON DELETE [A-Z ]+ ON UPDATE [A-Z ]+)*/
1079
+ /CONSTRAINT `(.+)` FOREIGN KEY \(`(.+)`\) REFERENCES `(.+)` \(`(.+)`\)( ON [A-Z ]+)*/
1080
1080
  );
1081
1081
  if (!matched) {
1082
1082
  throw new Error(`인식할 수 없는 FOREIGN KEY CONSTRAINT ${line}`);
1083
1083
  }
1084
- const [, keyName, from, referencesTable, referencesField, _onClause] =
1084
+ const [, keyName, from, referencesTable, referencesField, onClause] =
1085
1085
  matched;
1086
- const onClause = _onClause ?? "";
1087
-
1088
- const { onDelete, onUpdate } = (() => {
1089
- // ON Clause가 둘다 있는 경우
1090
- if (
1091
- onClause.includes("ON DELETE") &&
1092
- onClause.includes("ON UPDATE")
1093
- ) {
1094
- const [, onDelete, onUpdate] = onClause.match(
1095
- /ON DELETE ([A-Z ]+) ON UPDATE ([A-Z ]+)/
1096
- )!;
1097
- return {
1098
- onDelete,
1099
- onUpdate,
1100
- };
1101
- }
1086
+ // console.debug({ tableName, line, onClause });
1102
1087
 
1103
- // 각각 있는 경우
1104
- const onDelete =
1105
- onClause.match(/ON DELETE ([A-Z ]+)( ON)*/)?.[1] ?? "NO ACTION";
1106
- const onUpdate =
1107
- onClause.match(/ON UPDATE ([A-Z ]+)/)?.[1] ?? "NO ACTION";
1108
- return {
1109
- onDelete,
1110
- onUpdate,
1111
- };
1112
- })();
1088
+ const [onUpdateFull, _onUpdate] =
1089
+ (onClause ?? "").match(/ON UPDATE ([A-Z ]+)$/) ?? [];
1090
+ const onUpdate = _onUpdate ?? "NO ACTION";
1091
+
1092
+ const onDelete =
1093
+ (onClause ?? "")
1094
+ .replace(onUpdateFull ?? "", "")
1095
+ .match(/ON DELETE ([A-Z ]+) /)?.[1] ?? "NO ACTION";
1113
1096
 
1114
1097
  return {
1115
1098
  keyName,
@@ -55,11 +55,8 @@ export type ListResult<T> = {
55
55
  rows: T[];
56
56
  total?: number;
57
57
  };
58
-
59
- export type EnumsLabel<T extends string, L extends "ko" | "en"> = {
60
- [key in T]: { [lang in L]: string };
61
- };
62
- export type EnumsLabelKo<T extends string> = EnumsLabel<T, "ko">;
58
+ export const SonamuQueryMode = z.enum(["both", "list", "count"]);
59
+ export type SonamuQueryMode = z.infer<typeof SonamuQueryMode>;
63
60
 
64
61
  /*
65
62
  SWR
@@ -578,6 +578,8 @@ export class Syncer {
578
578
  return this.resolveParamDec({
579
579
  name: (member as ts.PropertySignature).name as ts.Identifier,
580
580
  type: (member as ts.PropertySignature).type as ts.TypeNode,
581
+ optional:
582
+ (member as ts.PropertySignature).questionToken !== undefined,
581
583
  });
582
584
  }
583
585
  }),
@@ -971,7 +973,6 @@ export class Syncer {
971
973
  }
972
974
  })();
973
975
  if (filteredPathAndCodes.length === 0) {
974
- console.log("요거란 말이지?");
975
976
  throw new AlreadyProcessedException(
976
977
  "이미 경로에 모든 파일이 존재합니다."
977
978
  );
@@ -115,6 +115,7 @@ export class Template__generated extends Template {
115
115
  "zArrayable",
116
116
  "SQLDateTimeString",
117
117
  "SubsetQuery",
118
+ "SonamuQueryMode",
118
119
  ].filter((mod) => body.includes(mod));
119
120
 
120
121
  return {
@@ -210,7 +211,7 @@ z.object({
210
211
  search: ${entity.id}SearchField,
211
212
  keyword: z.string(),
212
213
  orderBy: ${entity.id}OrderBy,
213
- withoutCount: z.boolean(),
214
+ queryMode: SonamuQueryMode,
214
215
  id: zArrayable(z.number().int().positive()),${filterBody}
215
216
  }).partial();
216
217
  `.trim();
@@ -237,7 +238,6 @@ z.object({
237
238
  const subsetKeys = Object.keys(entity.subsets);
238
239
  const importKeys: string[] = [];
239
240
  const lines: string[] = [
240
- // `// Subsets: ${entity.id}`,
241
241
  ...subsetKeys
242
242
  .map((subsetKey) => {
243
243
  // 서브셋에서 FieldExpr[] 가져옴
@@ -271,31 +271,8 @@ z.object({
271
271
  .join(",")}]);`,
272
272
  `export type ${entity.names.module}SubsetKey = z.infer<typeof ${entity.names.module}SubsetKey>`,
273
273
  "",
274
- // "/* BEGIN- Server-side Only */",
275
- // // `import { SubsetQuery } from "sonamu";`,
276
- // `export const ${camelize(entity.id, true)}SubsetQueries:{ [key in ${
277
- // entity.names.module
278
- // }SubsetKey]: SubsetQuery} = ${JSON.stringify(subsetQueryObject)}`,
279
- // "",
280
274
  ];
281
275
 
282
- // ServerSide Only
283
- // const subsetQueryObject = subsetKeys.reduce(
284
- // (r, subsetKey) => {
285
- // const subsetQuery = entity.getSubsetQuery(subsetKey);
286
- // r[subsetKey] = subsetQuery;
287
- // return r;
288
- // },
289
- // {} as {
290
- // [key: string]: SubsetQuery;
291
- // }
292
- // );
293
- // const lines2: string[] = [
294
- // `export const ${camelize(entity.id, true)}SubsetQueries:{ [key in ${
295
- // entity.names.module
296
- // }SubsetKey]: SubsetQuery} = ${JSON.stringify(subsetQueryObject)}`,
297
- // ];
298
-
299
276
  return {
300
277
  label: `Subsets: ${entity.id}`,
301
278
  lines,
@@ -251,6 +251,7 @@ export class Template__view_list extends Template {
251
251
  .filter(
252
252
  (col) =>
253
253
  col.name !== "id" &&
254
+ col.name !== "queryMode" &&
254
255
  (["enums", "number-id"].includes(col.renderType) ||
255
256
  col.name.endsWith("_id"))
256
257
  )
@@ -576,7 +577,6 @@ export function getEnumInfoFromColName(
576
577
  underscore(entityId) + "_" + underscore(colName),
577
578
  false
578
579
  );
579
- console.log({ idCandidate });
580
580
  try {
581
581
  const targetEntityNames = EntityManager.getNamesFromId(entityId);
582
582
  return {
@@ -67,7 +67,7 @@ export class FixtureManagerClass {
67
67
  const [tables] = await this.tdb.raw(
68
68
  "SHOW TABLE STATUS WHERE Engine IS NOT NULL"
69
69
  );
70
- return tables.map((tableInfo: any) => tableInfo["Name"]);
70
+ return tables.map((tableInfo: any) => tableInfo["Name"] as string);
71
71
  })();
72
72
 
73
73
  await this.tdb.raw(`SET FOREIGN_KEY_CHECKS = 0`);
@@ -359,6 +359,10 @@ export type SubsetQuery = {
359
359
  loaders: SubsetLoader[];
360
360
  };
361
361
 
362
+ /* BaseModel */
363
+ export const SonamuQueryMode = z.enum(["both", "list", "count"]);
364
+ export type SonamuQueryMode = z.infer<typeof SonamuQueryMode>;
365
+
362
366
  /* Knex Migration */
363
367
  export type KnexError = {
364
368
  code: string;
@@ -24,10 +24,10 @@ export function objToMap<T>(obj: { [k: string]: T }) {
24
24
  }
25
25
  }
26
26
 
27
- export class BaseListParams {
27
+ export interface BaseListParams {
28
28
  id?: number | number[];
29
29
  num?: number;
30
30
  page?: number;
31
31
  keyword?: string;
32
- withoutCount?: boolean;
32
+ queryMode?: "list" | "count" | "both";
33
33
  }