sonamu 0.4.13 → 0.5.0
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/.swcrc +15 -0
- package/dist/api/base-frame.d.ts +8 -0
- package/dist/api/base-frame.d.ts.map +1 -0
- package/dist/api/base-frame.js +2 -0
- package/dist/api/base-frame.js.map +1 -0
- package/dist/api/caster.d.ts +5 -0
- package/dist/api/caster.d.ts.map +1 -0
- package/dist/api/caster.js +2 -0
- package/dist/api/caster.js.map +1 -0
- package/dist/api/code-converters.d.ts +23 -0
- package/dist/api/code-converters.d.ts.map +1 -0
- package/dist/api/code-converters.js +2 -0
- package/dist/api/code-converters.js.map +1 -0
- package/dist/api/context.d.ts +16 -0
- package/dist/api/context.d.ts.map +1 -0
- package/dist/api/context.js +2 -0
- package/dist/api/context.js.map +1 -0
- package/dist/api/decorators.d.ts +50 -0
- package/dist/api/decorators.d.ts.map +1 -0
- package/dist/api/decorators.js +2 -0
- package/dist/api/decorators.js.map +1 -0
- package/dist/api/index.d.ts +8 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +2 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/sonamu.d.ts +83 -0
- package/dist/api/sonamu.d.ts.map +1 -0
- package/dist/api/sonamu.js +2 -0
- package/dist/api/sonamu.js.map +1 -0
- package/dist/api/sonamu.types.d.ts +30 -0
- package/dist/api/sonamu.types.d.ts.map +1 -0
- package/dist/api/sonamu.types.js +2 -0
- package/dist/api/sonamu.types.js.map +1 -0
- package/dist/bin/build-config.d.ts +5 -0
- package/dist/bin/build-config.d.ts.map +1 -0
- package/dist/bin/build-config.js +2 -0
- package/dist/bin/build-config.js.map +1 -0
- package/dist/bin/cli-wrapper.d.ts +2 -0
- package/dist/bin/cli-wrapper.d.ts.map +1 -0
- package/dist/bin/cli-wrapper.js +1 -38
- package/dist/bin/cli-wrapper.js.map +1 -1
- package/dist/bin/cli.d.ts +2 -2
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +1 -903
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/cli.mjs +2 -2
- package/dist/{chunk-DMJSNO2L.js → chunk-2WAC2GER.js} +44 -44
- package/dist/{chunk-DMJSNO2L.js.map → chunk-2WAC2GER.js.map} +1 -1
- package/dist/{chunk-NI37CY4T.mjs → chunk-C3IPIF6O.mjs} +2 -2
- package/dist/{chunk-DYFCACHD.js → chunk-EXHKSVTE.js} +7 -7
- package/dist/{chunk-QJFHDCBN.mjs → chunk-FCERKIIF.mjs} +2 -2
- package/dist/chunk-FCERKIIF.mjs.map +1 -0
- package/dist/{chunk-DDJ7T4MA.mjs → chunk-HGIBJYOU.mjs} +2 -2
- package/dist/{chunk-NIFOTHBW.mjs → chunk-JKSOJRQA.mjs} +2 -2
- package/dist/{chunk-CXAVBVKC.js → chunk-OTKKFP3Y.js} +100 -100
- package/dist/{chunk-J6S43O7G.js → chunk-UZ2IY5VE.js} +4 -4
- package/dist/database/_batch_update.d.ts +15 -0
- package/dist/database/_batch_update.d.ts.map +1 -0
- package/dist/database/_batch_update.js +2 -0
- package/dist/database/_batch_update.js.map +1 -0
- package/dist/database/base-model.d.ts +41 -0
- package/dist/database/base-model.d.ts.map +1 -0
- package/dist/database/base-model.js +2 -0
- package/dist/database/base-model.js.map +1 -0
- package/dist/database/code-generator.d.ts +13 -0
- package/dist/database/code-generator.d.ts.map +1 -0
- package/dist/database/code-generator.js +2 -0
- package/dist/database/code-generator.js.map +1 -0
- package/dist/database/db.d.ts +40 -0
- package/dist/database/db.d.ts.map +1 -0
- package/dist/database/db.js +2 -0
- package/dist/database/db.js.map +1 -0
- package/dist/database/drivers/knex/base-model.js +8 -8
- package/dist/database/drivers/knex/base-model.mjs +3 -3
- package/dist/database/drivers/kysely/base-model.js +9 -9
- package/dist/database/drivers/kysely/base-model.mjs +3 -3
- package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts +2 -0
- package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts.map +1 -0
- package/dist/database/knex-plugins/knex-on-duplicate-update.js +2 -0
- package/dist/database/knex-plugins/knex-on-duplicate-update.js.map +1 -0
- package/dist/database/puri-wrapper.d.ts +34 -0
- package/dist/database/puri-wrapper.d.ts.map +1 -0
- package/dist/database/puri-wrapper.js +2 -0
- package/dist/database/puri-wrapper.js.map +1 -0
- package/dist/database/puri.d.ts +83 -0
- package/dist/database/puri.d.ts.map +1 -0
- package/dist/database/puri.js +2 -0
- package/dist/database/puri.js.map +1 -0
- package/dist/database/puri.types.d.ts +60 -0
- package/dist/database/puri.types.d.ts.map +1 -0
- package/dist/database/puri.types.js +2 -0
- package/dist/database/puri.types.js.map +1 -0
- package/dist/database/transaction-context.d.ts +9 -0
- package/dist/database/transaction-context.d.ts.map +1 -0
- package/dist/database/transaction-context.js +2 -0
- package/dist/database/transaction-context.js.map +1 -0
- package/dist/database/types.d.ts +39 -0
- package/dist/database/types.d.ts.map +1 -0
- package/dist/database/types.js +2 -0
- package/dist/database/types.js.map +1 -0
- package/dist/database/upsert-builder.d.ts +34 -0
- package/dist/database/upsert-builder.d.ts.map +1 -0
- package/dist/database/upsert-builder.js +2 -0
- package/dist/database/upsert-builder.js.map +1 -0
- package/dist/entity/entity-manager.d.ts +32 -0
- package/dist/entity/entity-manager.d.ts.map +1 -0
- package/dist/entity/entity-manager.js +2 -0
- package/dist/entity/entity-manager.js.map +1 -0
- package/dist/entity/entity-utils.d.ts +61 -0
- package/dist/entity/entity-utils.d.ts.map +1 -0
- package/dist/entity/entity-utils.js +2 -0
- package/dist/entity/entity-utils.js.map +1 -0
- package/dist/entity/entity.d.ts +62 -0
- package/dist/entity/entity.d.ts.map +1 -0
- package/dist/entity/entity.js +2 -0
- package/dist/entity/entity.js.map +1 -0
- package/dist/entity/migrator.d.ts +135 -0
- package/dist/entity/migrator.d.ts.map +1 -0
- package/dist/entity/migrator.js +2 -0
- package/dist/entity/migrator.js.map +1 -0
- package/dist/exceptions/error-handler.d.ts +3 -0
- package/dist/exceptions/error-handler.d.ts.map +1 -0
- package/dist/exceptions/error-handler.js +2 -0
- package/dist/exceptions/error-handler.js.map +1 -0
- package/dist/exceptions/so-exceptions.d.ts +48 -0
- package/dist/exceptions/so-exceptions.d.ts.map +1 -0
- package/dist/exceptions/so-exceptions.js +2 -0
- package/dist/exceptions/so-exceptions.js.map +1 -0
- package/dist/file-storage/driver.d.ts +45 -0
- package/dist/file-storage/driver.d.ts.map +1 -0
- package/dist/file-storage/driver.js +2 -0
- package/dist/file-storage/driver.js.map +1 -0
- package/dist/file-storage/file-storage.d.ts +50 -0
- package/dist/file-storage/file-storage.d.ts.map +1 -0
- package/dist/file-storage/file-storage.js +2 -0
- package/dist/file-storage/file-storage.js.map +1 -0
- package/dist/index.d.ts +22 -813
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -433
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/migration/code-generation.d.ts +15 -0
- package/dist/migration/code-generation.d.ts.map +1 -0
- package/dist/migration/code-generation.js +2 -0
- package/dist/migration/code-generation.js.map +1 -0
- package/dist/migration/migration-set.d.ts +17 -0
- package/dist/migration/migration-set.d.ts.map +1 -0
- package/dist/migration/migration-set.js +2 -0
- package/dist/migration/migration-set.js.map +1 -0
- package/dist/migration/migrator.d.ts +130 -0
- package/dist/migration/migrator.d.ts.map +1 -0
- package/dist/migration/migrator.js +2 -0
- package/dist/migration/migrator.js.map +1 -0
- package/dist/migration/types.d.ts +52 -0
- package/dist/migration/types.d.ts.map +1 -0
- package/dist/migration/types.js +2 -0
- package/dist/migration/types.js.map +1 -0
- package/dist/smd/smd-manager.d.ts +28 -0
- package/dist/smd/smd-manager.d.ts.map +1 -0
- package/dist/smd/smd-manager.js +2 -0
- package/dist/smd/smd-manager.js.map +1 -0
- package/dist/smd/smd.d.ts +40 -0
- package/dist/smd/smd.d.ts.map +1 -0
- package/dist/smd/smd.js +2 -0
- package/dist/smd/smd.js.map +1 -0
- package/dist/syncer/index.d.ts +2 -0
- package/dist/syncer/index.d.ts.map +1 -0
- package/dist/syncer/index.js +2 -0
- package/dist/syncer/index.js.map +1 -0
- package/dist/syncer/syncer.d.ts +127 -0
- package/dist/syncer/syncer.d.ts.map +1 -0
- package/dist/syncer/syncer.js +2 -0
- package/dist/syncer/syncer.js.map +1 -0
- package/dist/templates/base-template.d.ts +13 -0
- package/dist/templates/base-template.d.ts.map +1 -0
- package/dist/templates/base-template.js +2 -0
- package/dist/templates/base-template.js.map +1 -0
- package/dist/templates/entity.template.d.ts +17 -0
- package/dist/templates/entity.template.d.ts.map +1 -0
- package/dist/templates/entity.template.js +2 -0
- package/dist/templates/entity.template.js.map +1 -0
- package/dist/templates/generated.template.d.ts +27 -0
- package/dist/templates/generated.template.d.ts.map +1 -0
- package/dist/templates/generated.template.js +2 -0
- package/dist/templates/generated.template.js.map +1 -0
- package/dist/templates/generated_http.template.d.ts +24 -0
- package/dist/templates/generated_http.template.d.ts.map +1 -0
- package/dist/templates/generated_http.template.js +2 -0
- package/dist/templates/generated_http.template.js.map +1 -0
- package/dist/templates/generated_sso.template.d.ts +20 -0
- package/dist/templates/generated_sso.template.d.ts.map +1 -0
- package/dist/templates/generated_sso.template.js +2 -0
- package/dist/templates/generated_sso.template.js.map +1 -0
- package/dist/templates/index.d.ts +2 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +2 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/templates/init_types.template.d.ts +17 -0
- package/dist/templates/init_types.template.d.ts.map +1 -0
- package/dist/templates/init_types.template.js +2 -0
- package/dist/templates/init_types.template.js.map +1 -0
- package/dist/templates/model.template.d.ts +17 -0
- package/dist/templates/model.template.d.ts.map +1 -0
- package/dist/templates/model.template.js +2 -0
- package/dist/templates/model.template.js.map +1 -0
- package/dist/templates/model_test.template.d.ts +17 -0
- package/dist/templates/model_test.template.d.ts.map +1 -0
- package/dist/templates/model_test.template.js +2 -0
- package/dist/templates/model_test.template.js.map +1 -0
- package/dist/templates/service.template.d.ts +29 -0
- package/dist/templates/service.template.d.ts.map +1 -0
- package/dist/templates/service.template.js +2 -0
- package/dist/templates/service.template.js.map +1 -0
- package/dist/templates/view_enums_buttonset.template.d.ts +17 -0
- package/dist/templates/view_enums_buttonset.template.d.ts.map +1 -0
- package/dist/templates/view_enums_buttonset.template.js +2 -0
- package/dist/templates/view_enums_buttonset.template.js.map +1 -0
- package/dist/templates/view_enums_dropdown.template.d.ts +18 -0
- package/dist/templates/view_enums_dropdown.template.d.ts.map +1 -0
- package/dist/templates/view_enums_dropdown.template.js +2 -0
- package/dist/templates/view_enums_dropdown.template.js.map +1 -0
- package/dist/templates/view_enums_select.template.d.ts +17 -0
- package/dist/templates/view_enums_select.template.d.ts.map +1 -0
- package/dist/templates/view_enums_select.template.js +2 -0
- package/dist/templates/view_enums_select.template.js.map +1 -0
- package/dist/templates/view_form.template.d.ts +26 -0
- package/dist/templates/view_form.template.d.ts.map +1 -0
- package/dist/templates/view_form.template.js +2 -0
- package/dist/templates/view_form.template.js.map +1 -0
- package/dist/templates/view_id_all_select.template.d.ts +17 -0
- package/dist/templates/view_id_all_select.template.d.ts.map +1 -0
- package/dist/templates/view_id_all_select.template.js +2 -0
- package/dist/templates/view_id_all_select.template.js.map +1 -0
- package/dist/templates/view_id_async_select.template.d.ts +17 -0
- package/dist/templates/view_id_async_select.template.d.ts.map +1 -0
- package/dist/templates/view_id_async_select.template.js +2 -0
- package/dist/templates/view_id_async_select.template.js.map +1 -0
- package/dist/templates/view_list.template.d.ts +38 -0
- package/dist/templates/view_list.template.d.ts.map +1 -0
- package/dist/templates/view_list.template.js +2 -0
- package/dist/templates/view_list.template.js.map +1 -0
- package/dist/templates/view_list_columns.template.d.ts +17 -0
- package/dist/templates/view_list_columns.template.d.ts.map +1 -0
- package/dist/templates/view_list_columns.template.js +2 -0
- package/dist/templates/view_list_columns.template.js.map +1 -0
- package/dist/templates/view_search_input.template.d.ts +17 -0
- package/dist/templates/view_search_input.template.d.ts.map +1 -0
- package/dist/templates/view_search_input.template.js +2 -0
- package/dist/templates/view_search_input.template.js.map +1 -0
- package/dist/testing/_relation-graph.d.ts +7 -0
- package/dist/testing/_relation-graph.d.ts.map +1 -0
- package/dist/testing/_relation-graph.js +2 -0
- package/dist/testing/_relation-graph.js.map +1 -0
- package/dist/testing/fixture-manager.d.ts +35 -0
- package/dist/testing/fixture-manager.d.ts.map +1 -0
- package/dist/testing/fixture-manager.js +2 -0
- package/dist/testing/fixture-manager.js.map +1 -0
- package/dist/types/types.d.ts +609 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/types.js +2 -0
- package/dist/types/types.js.map +1 -0
- package/dist/typings/knex.d.js +2 -0
- package/dist/typings/knex.d.js.map +1 -0
- package/dist/utils/async-utils.d.ts +25 -0
- package/dist/utils/async-utils.d.ts.map +1 -0
- package/dist/utils/async-utils.js +2 -0
- package/dist/utils/async-utils.js.map +1 -0
- package/dist/utils/controller.d.ts +9 -0
- package/dist/utils/controller.d.ts.map +1 -0
- package/dist/utils/controller.js +2 -0
- package/dist/utils/controller.js.map +1 -0
- package/dist/utils/fs-utils.d.ts +9 -0
- package/dist/utils/fs-utils.d.ts.map +1 -0
- package/dist/utils/fs-utils.js +2 -0
- package/dist/utils/fs-utils.js.map +1 -0
- package/dist/utils/lodash-able.d.ts +2 -0
- package/dist/utils/lodash-able.d.ts.map +1 -0
- package/dist/utils/lodash-able.js +2 -0
- package/dist/utils/lodash-able.js.map +1 -0
- package/dist/utils/model.d.ts +17 -0
- package/dist/utils/model.d.ts.map +1 -0
- package/dist/utils/model.js +2 -0
- package/dist/utils/model.js.map +1 -0
- package/dist/utils/sql-parser.d.ts +4 -0
- package/dist/utils/sql-parser.d.ts.map +1 -0
- package/dist/utils/sql-parser.js +2 -0
- package/dist/utils/sql-parser.js.map +1 -0
- package/dist/utils/utils.d.ts +9 -0
- package/dist/utils/utils.d.ts.map +1 -0
- package/dist/utils/utils.js +2 -0
- package/dist/utils/utils.js.map +1 -0
- package/dist/utils/zod-error.d.ts +8 -0
- package/dist/utils/zod-error.d.ts.map +1 -0
- package/dist/utils/zod-error.js +2 -0
- package/dist/utils/zod-error.js.map +1 -0
- package/nodemon.json +6 -0
- package/package.json +29 -44
- package/src/api/base-frame.ts +3 -4
- package/src/api/caster.ts +22 -23
- package/src/api/code-converters.ts +170 -134
- package/src/api/context.ts +13 -6
- package/src/api/decorators.ts +146 -20
- package/src/api/index.ts +2 -0
- package/src/api/sonamu.ts +374 -165
- package/src/bin/build-config.ts +5 -0
- package/src/bin/cli-wrapper.ts +29 -40
- package/src/bin/cli.ts +132 -190
- package/src/database/_batch_update.ts +10 -15
- package/src/database/base-model.ts +300 -216
- package/src/database/db.ts +191 -21
- package/src/database/{drivers/knex/plugins → knex-plugins}/knex-on-duplicate-update.ts +1 -1
- package/src/database/puri-wrapper.ts +129 -0
- package/src/database/puri.ts +808 -0
- package/src/database/puri.types.ts +222 -0
- package/src/database/transaction-context.ts +18 -0
- package/src/database/upsert-builder.ts +32 -35
- package/src/entity/entity-manager.ts +7 -15
- package/src/entity/entity.ts +9 -31
- package/src/entity/migrator-/354/235/264/354/202/254/352/260/224/354/226/264/354/232/224.md +1 -0
- package/src/file-storage/driver.ts +121 -0
- package/src/file-storage/file-storage.ts +100 -0
- package/src/index.ts +14 -11
- package/src/migration/code-generation.ts +777 -0
- package/src/migration/migration-set.ts +453 -0
- package/src/migration/migrator.ts +823 -0
- package/src/migration/types.ts +53 -0
- package/src/shared/web.shared.ts.txt +33 -2
- package/src/syncer/syncer.ts +294 -127
- package/src/templates/generated.template.ts +13 -1
- package/src/templates/generated_http.template.ts +15 -12
- package/src/templates/generated_sso.template.ts +50 -2
- package/src/templates/model.template.ts +138 -2
- package/src/templates/service.template.ts +0 -1
- package/src/templates/view_form.template.ts +11 -7
- package/src/templates/view_list.template.ts +12 -4
- package/src/testing/fixture-manager.ts +229 -174
- package/src/types/types.ts +102 -14
- package/src/utils/async-utils.ts +64 -0
- package/src/utils/fs-utils.ts +17 -0
- package/src/utils/model.ts +0 -2
- package/src/utils/utils.ts +14 -58
- package/src/utils/zod-error.ts +12 -176
- package/tsconfig.json +2 -0
- package/tsup.config.js +4 -2
- package/.pnp.cjs +0 -14363
- package/.pnp.loader.mjs +0 -2047
- package/.vscode/extensions.json +0 -6
- package/.vscode/settings.json +0 -9
- package/.yarnrc.yml +0 -5
- package/dist/chunk-QJFHDCBN.mjs.map +0 -1
- package/src/database/base-model.abstract.ts +0 -97
- package/src/database/db.abstract.ts +0 -75
- package/src/database/drivers/knex/base-model.ts +0 -55
- package/src/database/drivers/knex/client.ts +0 -209
- package/src/database/drivers/knex/db.ts +0 -232
- package/src/database/drivers/knex/generator.ts +0 -659
- package/src/database/drivers/kysely/base-model.ts +0 -89
- package/src/database/drivers/kysely/client.ts +0 -309
- package/src/database/drivers/kysely/db.ts +0 -238
- package/src/database/drivers/kysely/generator.ts +0 -714
- package/src/database/types.ts +0 -118
- package/src/entity/migrator.ts +0 -1400
- package/src/smd/smd-manager.ts +0 -139
- package/src/smd/smd.ts +0 -571
- package/src/templates/kysely_types.template.ts +0 -205
- /package/dist/{chunk-NI37CY4T.mjs.map → chunk-C3IPIF6O.mjs.map} +0 -0
- /package/dist/{chunk-DYFCACHD.js.map → chunk-EXHKSVTE.js.map} +0 -0
- /package/dist/{chunk-DDJ7T4MA.mjs.map → chunk-HGIBJYOU.mjs.map} +0 -0
- /package/dist/{chunk-NIFOTHBW.mjs.map → chunk-JKSOJRQA.mjs.map} +0 -0
- /package/dist/{chunk-CXAVBVKC.js.map → chunk-OTKKFP3Y.js.map} +0 -0
- /package/dist/{chunk-J6S43O7G.js.map → chunk-UZ2IY5VE.js.map} +0 -0
|
@@ -19,69 +19,138 @@ import { Entity } from "../entity/entity";
|
|
|
19
19
|
import inflection from "inflection";
|
|
20
20
|
import { readFileSync, writeFileSync } from "fs";
|
|
21
21
|
import { RelationGraph } from "./_relation-graph";
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import { KnexClient } from "../database/drivers/knex/client";
|
|
22
|
+
import knex, { Knex } from "knex";
|
|
23
|
+
import { BaseModel } from "../database/base-model";
|
|
24
|
+
import { SonamuDBConfig } from "../database/db";
|
|
26
25
|
|
|
27
26
|
export class FixtureManagerClass {
|
|
27
|
+
private _tdb: Knex | null = null;
|
|
28
|
+
set tdb(tdb: Knex) {
|
|
29
|
+
this._tdb = tdb;
|
|
30
|
+
}
|
|
31
|
+
get tdb(): Knex {
|
|
32
|
+
if (this._tdb === null) {
|
|
33
|
+
throw new Error("FixtureManager has not been initialized");
|
|
34
|
+
}
|
|
35
|
+
return this._tdb;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private _fdb: Knex | null = null;
|
|
39
|
+
set fdb(fdb: Knex) {
|
|
40
|
+
this._fdb = fdb;
|
|
41
|
+
}
|
|
42
|
+
get fdb(): Knex {
|
|
43
|
+
if (this._fdb === null) {
|
|
44
|
+
throw new Error("FixtureManager has not been initialized");
|
|
45
|
+
}
|
|
46
|
+
return this._fdb;
|
|
47
|
+
}
|
|
48
|
+
cachedTableNames: string[] | null = null;
|
|
49
|
+
|
|
28
50
|
private relationGraph = new RelationGraph();
|
|
29
51
|
|
|
30
52
|
init() {
|
|
31
|
-
|
|
53
|
+
if (this._tdb !== null) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (Sonamu.dbConfig.test && Sonamu.dbConfig.production_master) {
|
|
57
|
+
const tConn = Sonamu.dbConfig.test.connection as Knex.ConnectionConfig & {
|
|
58
|
+
port?: number;
|
|
59
|
+
};
|
|
60
|
+
const pConn = Sonamu.dbConfig.production_master
|
|
61
|
+
.connection as Knex.ConnectionConfig & { port?: number };
|
|
62
|
+
if (
|
|
63
|
+
`${tConn.host ?? "localhost"}:${tConn.port ?? 3306}/${
|
|
64
|
+
tConn.database
|
|
65
|
+
}` ===
|
|
66
|
+
`${pConn.host ?? "localhost"}:${pConn.port ?? 3306}/${pConn.database}`
|
|
67
|
+
) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
`테스트DB와 프로덕션DB에 동일한 데이터베이스가 사용되었습니다.`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
this.tdb = knex(Sonamu.dbConfig.test);
|
|
75
|
+
this.fdb = knex(Sonamu.dbConfig.fixture_local);
|
|
32
76
|
}
|
|
33
77
|
|
|
34
78
|
async cleanAndSeed(usingTables?: string[]) {
|
|
35
|
-
const tableNames = await (async () => {
|
|
79
|
+
const tableNames: string[] = await (async () => {
|
|
36
80
|
if (usingTables) {
|
|
37
81
|
return usingTables;
|
|
38
82
|
}
|
|
83
|
+
if (this.cachedTableNames) {
|
|
84
|
+
return this.cachedTableNames;
|
|
85
|
+
}
|
|
39
86
|
|
|
40
|
-
const tables = await
|
|
41
|
-
`SHOW TABLE STATUS WHERE Engine IS NOT NULL`
|
|
87
|
+
const [tables] = await this.tdb.raw(
|
|
88
|
+
`SHOW TABLE STATUS WHERE Engine IS NOT NULL AND Name != 'migrations'`
|
|
42
89
|
);
|
|
43
|
-
|
|
90
|
+
const tableNames = tables.map(
|
|
91
|
+
(tableInfo: { Name: string }) => tableInfo["Name"]
|
|
92
|
+
);
|
|
93
|
+
this.cachedTableNames = tableNames;
|
|
94
|
+
return tableNames;
|
|
44
95
|
})();
|
|
45
96
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (tableName == "migrations") {
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
97
|
+
// migrations 제외한 테이블 목록
|
|
98
|
+
const tableListStr = tableNames.join(", ");
|
|
51
99
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
100
|
+
// 한 번에 모든 테이블 체크섬 확인
|
|
101
|
+
const [fdbChecksumRows] = await this.fdb.raw<
|
|
102
|
+
[{ Table: string; Checksum: number }[]]
|
|
103
|
+
>(`CHECKSUM TABLE ${tableListStr}`);
|
|
104
|
+
const [tdbChecksumRows] = await this.tdb.raw<
|
|
105
|
+
[{ Table: string; Checksum: number }[]]
|
|
106
|
+
>(`CHECKSUM TABLE ${tableListStr}`);
|
|
56
107
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
)
|
|
60
|
-
|
|
108
|
+
// 체크섬 맵 생성
|
|
109
|
+
const fdbChecksums = new Map(
|
|
110
|
+
fdbChecksumRows.map((row) => [row.Table.split(".").pop()!, row.Checksum])
|
|
111
|
+
);
|
|
112
|
+
const tdbChecksums = new Map(
|
|
113
|
+
tdbChecksumRows.map((row) => [row.Table.split(".").pop()!, row.Checksum])
|
|
114
|
+
);
|
|
61
115
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
116
|
+
// 변경된 테이블들만 처리
|
|
117
|
+
const changedTables = tableNames.filter(
|
|
118
|
+
(tableName) => fdbChecksums.get(tableName) !== tdbChecksums.get(tableName)
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
// 병렬로 truncate + insert 실행
|
|
122
|
+
await this.tdb.transaction(async (trx) => {
|
|
123
|
+
await trx.raw(`SET FOREIGN_KEY_CHECKS = 0`);
|
|
124
|
+
|
|
125
|
+
await Promise.all(
|
|
126
|
+
changedTables.map(async (tableName) => {
|
|
127
|
+
await trx.raw(`SET FOREIGN_KEY_CHECKS = 0`);
|
|
128
|
+
await trx(tableName).truncate();
|
|
129
|
+
const rawQuery = `INSERT INTO ${
|
|
130
|
+
(Sonamu.dbConfig.test.connection as Knex.ConnectionConfig).database
|
|
131
|
+
}.${tableName}
|
|
132
|
+
SELECT * FROM ${
|
|
133
|
+
(Sonamu.dbConfig.fixture_local.connection as Knex.ConnectionConfig)
|
|
134
|
+
.database
|
|
135
|
+
}.${tableName}`;
|
|
136
|
+
await trx.raw(rawQuery);
|
|
137
|
+
})
|
|
138
|
+
);
|
|
139
|
+
await trx.raw(`SET FOREIGN_KEY_CHECKS = 1`);
|
|
140
|
+
});
|
|
70
141
|
|
|
71
142
|
// console.timeEnd("FIXTURE-CleanAndSeed");
|
|
72
143
|
}
|
|
73
144
|
|
|
74
|
-
async getChecksum(db:
|
|
75
|
-
const [checksumRow] = await db.raw
|
|
76
|
-
`CHECKSUM TABLE ${tableName}`
|
|
77
|
-
);
|
|
145
|
+
async getChecksum(db: Knex, tableName: string) {
|
|
146
|
+
const [[checksumRow]] = await db.raw(`CHECKSUM TABLE ${tableName}`);
|
|
78
147
|
return checksumRow.Checksum;
|
|
79
148
|
}
|
|
80
149
|
|
|
81
150
|
async sync() {
|
|
82
|
-
const frdb =
|
|
151
|
+
const frdb = knex(Sonamu.dbConfig.fixture_remote);
|
|
83
152
|
|
|
84
|
-
const tables = await
|
|
153
|
+
const [tables] = await this.fdb.raw(
|
|
85
154
|
"SHOW TABLE STATUS WHERE Engine IS NOT NULL"
|
|
86
155
|
);
|
|
87
156
|
const tableNames: string[] = tables.map(
|
|
@@ -91,44 +160,46 @@ export class FixtureManagerClass {
|
|
|
91
160
|
console.log(chalk.magenta("SYNC..."));
|
|
92
161
|
await Promise.all(
|
|
93
162
|
tableNames.map(async (tableName) => {
|
|
94
|
-
if (tableName.startsWith(
|
|
163
|
+
if (tableName.startsWith("knex_migrations")) {
|
|
95
164
|
return;
|
|
96
165
|
}
|
|
97
166
|
|
|
98
167
|
const remoteChecksum = await this.getChecksum(frdb, tableName);
|
|
99
|
-
const localChecksum = await this.getChecksum(
|
|
168
|
+
const localChecksum = await this.getChecksum(this.fdb, tableName);
|
|
100
169
|
|
|
101
170
|
if (remoteChecksum !== localChecksum) {
|
|
102
|
-
await
|
|
171
|
+
await this.fdb.transaction(async (transaction) => {
|
|
103
172
|
await transaction.raw(`SET FOREIGN_KEY_CHECKS = 0`);
|
|
104
|
-
await transaction.truncate(
|
|
173
|
+
await transaction(tableName).truncate();
|
|
105
174
|
|
|
106
|
-
const rows = await frdb
|
|
175
|
+
const rows = await frdb(tableName);
|
|
107
176
|
if (rows.length === 0) {
|
|
108
177
|
return;
|
|
109
178
|
}
|
|
110
179
|
|
|
111
180
|
console.log(chalk.blue(tableName), rows.length);
|
|
112
|
-
await transaction
|
|
113
|
-
|
|
114
|
-
.map((
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
181
|
+
await transaction
|
|
182
|
+
.insert(
|
|
183
|
+
rows.map((row: any) => {
|
|
184
|
+
return Object.fromEntries(
|
|
185
|
+
Object.entries(row).map(([key, value]) => {
|
|
186
|
+
if (value === null) {
|
|
187
|
+
return [key, null];
|
|
188
|
+
} else if (typeof value === "boolean") {
|
|
189
|
+
return [key, value ? 1 : 0];
|
|
190
|
+
} else if (
|
|
191
|
+
typeof value === "object" &&
|
|
192
|
+
!(value instanceof Date)
|
|
193
|
+
) {
|
|
194
|
+
return [key, JSON.stringify(value)];
|
|
195
|
+
} else {
|
|
196
|
+
return [key, value];
|
|
197
|
+
}
|
|
198
|
+
})
|
|
199
|
+
);
|
|
200
|
+
})
|
|
201
|
+
)
|
|
202
|
+
.into(tableName);
|
|
132
203
|
console.log("OK");
|
|
133
204
|
await transaction.raw(`SET FOREIGN_KEY_CHECKS = 1`);
|
|
134
205
|
});
|
|
@@ -140,7 +211,11 @@ export class FixtureManagerClass {
|
|
|
140
211
|
await frdb.destroy();
|
|
141
212
|
}
|
|
142
213
|
|
|
214
|
+
private visitedRecords = new Set<string>();
|
|
143
215
|
async importFixture(entityId: string, ids: number[]) {
|
|
216
|
+
// 방문 기록 초기화 (새로운 import 작업 시작)
|
|
217
|
+
this.visitedRecords.clear();
|
|
218
|
+
|
|
144
219
|
const queries = _.uniq(
|
|
145
220
|
(
|
|
146
221
|
await Promise.all(
|
|
@@ -151,9 +226,9 @@ export class FixtureManagerClass {
|
|
|
151
226
|
).flat()
|
|
152
227
|
);
|
|
153
228
|
|
|
154
|
-
const wdb =
|
|
229
|
+
const wdb = BaseModel.getDB("w");
|
|
155
230
|
for (let query of queries) {
|
|
156
|
-
const [rsh] = await wdb.raw
|
|
231
|
+
const [rsh] = await wdb.raw(query);
|
|
157
232
|
console.log({
|
|
158
233
|
query,
|
|
159
234
|
info: rsh.info,
|
|
@@ -166,21 +241,29 @@ export class FixtureManagerClass {
|
|
|
166
241
|
field: string,
|
|
167
242
|
id: number
|
|
168
243
|
): Promise<string[]> {
|
|
244
|
+
const recordKey = `${entityId}#${field}#${id}`;
|
|
245
|
+
|
|
246
|
+
// 순환 참조 방지: 이미 방문한 레코드는 스킵
|
|
247
|
+
if (this.visitedRecords.has(recordKey)) {
|
|
248
|
+
return [];
|
|
249
|
+
}
|
|
250
|
+
this.visitedRecords.add(recordKey);
|
|
251
|
+
|
|
169
252
|
console.log({ entityId, field, id });
|
|
170
253
|
const entity = EntityManager.get(entityId);
|
|
171
|
-
const wdb =
|
|
254
|
+
const wdb = BaseModel.getDB("w");
|
|
172
255
|
|
|
173
256
|
// 여기서 실DB의 row 가져옴
|
|
174
|
-
const [row] = await wdb.
|
|
175
|
-
`SELECT * FROM ${entity.table} WHERE ${field} = ${id} LIMIT 1`
|
|
176
|
-
);
|
|
257
|
+
const [row] = await wdb(entity.table).where(field, id).limit(1);
|
|
177
258
|
if (row === undefined) {
|
|
178
259
|
throw new Error(`${entityId}#${id} row를 찾을 수 없습니다.`);
|
|
179
260
|
}
|
|
180
261
|
|
|
181
262
|
// 픽스쳐DB, 실DB
|
|
182
|
-
const fixtureDatabase =
|
|
183
|
-
|
|
263
|
+
const fixtureDatabase = (Sonamu.dbConfig.fixture_remote.connection as any)
|
|
264
|
+
.database;
|
|
265
|
+
const realDatabase = (Sonamu.dbConfig.production_master.connection as any)
|
|
266
|
+
.database;
|
|
184
267
|
|
|
185
268
|
const selfQuery = `INSERT IGNORE INTO \`${fixtureDatabase}\`.\`${entity.table}\` (SELECT * FROM \`${realDatabase}\`.\`${entity.table}\` WHERE \`id\` = ${id})`;
|
|
186
269
|
|
|
@@ -203,7 +286,16 @@ export class FixtureManagerClass {
|
|
|
203
286
|
let field: string;
|
|
204
287
|
let id: number;
|
|
205
288
|
if (isOneToOneRelationProp(relation) && !relation.hasJoinColumn) {
|
|
206
|
-
|
|
289
|
+
const relatedEntity = EntityManager.get(relation.with);
|
|
290
|
+
const relatedIdColumnName = relatedEntity.props.find(
|
|
291
|
+
(p) => isRelationProp(p) && p.with === entity.id
|
|
292
|
+
)?.name;
|
|
293
|
+
if (!relatedIdColumnName) {
|
|
294
|
+
throw new Error(
|
|
295
|
+
`${relatedEntity.id}의 ${entity.id} 관계 프롭을 찾을 수 없습니다.`
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
field = `${relatedIdColumnName}_id`;
|
|
207
299
|
id = row["id"];
|
|
208
300
|
} else {
|
|
209
301
|
field = "id";
|
|
@@ -226,9 +318,16 @@ export class FixtureManagerClass {
|
|
|
226
318
|
return [..._.uniq(relQueries.reverse().flat()), selfQuery];
|
|
227
319
|
}
|
|
228
320
|
|
|
229
|
-
async
|
|
230
|
-
|
|
231
|
-
|
|
321
|
+
async destroy() {
|
|
322
|
+
if (this._tdb) {
|
|
323
|
+
await this._tdb.destroy();
|
|
324
|
+
this._tdb = null;
|
|
325
|
+
}
|
|
326
|
+
if (this._fdb) {
|
|
327
|
+
await this._fdb.destroy();
|
|
328
|
+
this._fdb = null;
|
|
329
|
+
}
|
|
330
|
+
await BaseModel.destroy();
|
|
232
331
|
}
|
|
233
332
|
|
|
234
333
|
async getFixtures(
|
|
@@ -236,8 +335,8 @@ export class FixtureManagerClass {
|
|
|
236
335
|
targetDBName: keyof SonamuDBConfig,
|
|
237
336
|
searchOptions: FixtureSearchOptions
|
|
238
337
|
) {
|
|
239
|
-
const sourceDB =
|
|
240
|
-
const targetDB =
|
|
338
|
+
const sourceDB = knex(Sonamu.dbConfig[sourceDBName]);
|
|
339
|
+
const targetDB = knex(Sonamu.dbConfig[targetDBName]);
|
|
241
340
|
const { entityId, field, value, searchType } = searchOptions;
|
|
242
341
|
|
|
243
342
|
const entity = EntityManager.get(entityId);
|
|
@@ -246,14 +345,14 @@ export class FixtureManagerClass {
|
|
|
246
345
|
? `${field}_id`
|
|
247
346
|
: field;
|
|
248
347
|
|
|
249
|
-
let query = sourceDB
|
|
348
|
+
let query = sourceDB(entity.table);
|
|
250
349
|
if (searchType === "equals") {
|
|
251
|
-
query = query.where(
|
|
350
|
+
query = query.where(column, value);
|
|
252
351
|
} else if (searchType === "like") {
|
|
253
|
-
query = query.where(
|
|
352
|
+
query = query.where(column, "like", `%${value}%`);
|
|
254
353
|
}
|
|
255
354
|
|
|
256
|
-
const rows = await query
|
|
355
|
+
const rows = await query;
|
|
257
356
|
if (rows.length === 0) {
|
|
258
357
|
throw new Error("No records found");
|
|
259
358
|
}
|
|
@@ -280,12 +379,7 @@ export class FixtureManagerClass {
|
|
|
280
379
|
const entity = EntityManager.get(fixture.entityId);
|
|
281
380
|
|
|
282
381
|
// ID를 이용하여 targetDB에 레코드가 존재하는지 확인
|
|
283
|
-
const
|
|
284
|
-
.from(entity.table)
|
|
285
|
-
.selectAll()
|
|
286
|
-
.where(["id", "=", fixture.id])
|
|
287
|
-
.first()
|
|
288
|
-
.execute();
|
|
382
|
+
const row = await targetDB(entity.table).where("id", fixture.id).first();
|
|
289
383
|
if (row) {
|
|
290
384
|
const [record] = await this.createFixtureRecord(entity, row, {
|
|
291
385
|
singleRecord: true,
|
|
@@ -318,7 +412,7 @@ export class FixtureManagerClass {
|
|
|
318
412
|
row: any,
|
|
319
413
|
options?: {
|
|
320
414
|
singleRecord?: boolean;
|
|
321
|
-
_db?:
|
|
415
|
+
_db?: Knex;
|
|
322
416
|
}
|
|
323
417
|
): Promise<FixtureRecord[]> {
|
|
324
418
|
const records: FixtureRecord[] = [];
|
|
@@ -350,27 +444,21 @@ export class FixtureManagerClass {
|
|
|
350
444
|
value: row[prop.name],
|
|
351
445
|
};
|
|
352
446
|
|
|
353
|
-
const db = options?._db ??
|
|
447
|
+
const db = options?._db ?? BaseModel.getDB("w");
|
|
354
448
|
if (isManyToManyRelationProp(prop)) {
|
|
355
449
|
const relatedEntity = EntityManager.get(prop.with);
|
|
356
450
|
const throughTable = prop.joinTable;
|
|
357
451
|
const fromColumn = `${inflection.singularize(entity.table)}_id`;
|
|
358
452
|
const toColumn = `${inflection.singularize(relatedEntity.table)}_id`;
|
|
359
453
|
|
|
360
|
-
const
|
|
361
|
-
.
|
|
362
|
-
.
|
|
363
|
-
.where([fromColumn, "=", row.id])
|
|
364
|
-
.execute();
|
|
365
|
-
const relatedIds = _relatedIds.map((r) => parseInt(r[toColumn]));
|
|
366
|
-
|
|
454
|
+
const relatedIds = await db(throughTable)
|
|
455
|
+
.where(fromColumn, row.id)
|
|
456
|
+
.pluck(toColumn);
|
|
367
457
|
record.columns[prop.name].value = relatedIds;
|
|
368
458
|
} else if (isHasManyRelationProp(prop)) {
|
|
369
459
|
const relatedEntity = EntityManager.get(prop.with);
|
|
370
|
-
const relatedIds = await db
|
|
371
|
-
.
|
|
372
|
-
.select("id")
|
|
373
|
-
.where([prop.joinColumn, "=", row.id])
|
|
460
|
+
const relatedIds = await db(relatedEntity.table)
|
|
461
|
+
.where(prop.joinColumn, row.id)
|
|
374
462
|
.pluck("id");
|
|
375
463
|
record.columns[prop.name].value = relatedIds;
|
|
376
464
|
} else if (isOneToOneRelationProp(prop) && !prop.hasJoinColumn) {
|
|
@@ -379,13 +467,9 @@ export class FixtureManagerClass {
|
|
|
379
467
|
(p) => isRelationProp(p) && p.with === entity.id
|
|
380
468
|
);
|
|
381
469
|
if (relatedProp) {
|
|
382
|
-
const
|
|
383
|
-
.
|
|
384
|
-
.
|
|
385
|
-
.where([relatedProp.name, "=", row.id])
|
|
386
|
-
.first()
|
|
387
|
-
.execute();
|
|
388
|
-
|
|
470
|
+
const relatedRow = await db(relatedEntity.table)
|
|
471
|
+
.where("id", row.id)
|
|
472
|
+
.first();
|
|
389
473
|
record.columns[prop.name].value = relatedRow?.id;
|
|
390
474
|
}
|
|
391
475
|
} else if (isRelationProp(prop)) {
|
|
@@ -396,12 +480,9 @@ export class FixtureManagerClass {
|
|
|
396
480
|
}
|
|
397
481
|
if (!options?.singleRecord && relatedId) {
|
|
398
482
|
const relatedEntity = EntityManager.get(prop.with);
|
|
399
|
-
const
|
|
400
|
-
.
|
|
401
|
-
.
|
|
402
|
-
.where(["id", "=", relatedId])
|
|
403
|
-
.first()
|
|
404
|
-
.execute();
|
|
483
|
+
const relatedRow = await db(relatedEntity.table)
|
|
484
|
+
.where("id", relatedId)
|
|
485
|
+
.first();
|
|
405
486
|
if (relatedRow) {
|
|
406
487
|
await create(relatedEntity, relatedRow);
|
|
407
488
|
}
|
|
@@ -425,9 +506,9 @@ export class FixtureManagerClass {
|
|
|
425
506
|
|
|
426
507
|
this.relationGraph.buildGraph(fixtures);
|
|
427
508
|
const insertionOrder = this.relationGraph.getInsertionOrder();
|
|
428
|
-
const db =
|
|
509
|
+
const db = knex(Sonamu.dbConfig[dbName]);
|
|
429
510
|
|
|
430
|
-
await db.
|
|
511
|
+
await db.transaction(async (trx) => {
|
|
431
512
|
await trx.raw(`SET FOREIGN_KEY_CHECKS = 0`);
|
|
432
513
|
|
|
433
514
|
for (const fixtureId of insertionOrder) {
|
|
@@ -466,12 +547,7 @@ export class FixtureManagerClass {
|
|
|
466
547
|
|
|
467
548
|
for await (const r of fixtures) {
|
|
468
549
|
const entity = EntityManager.get(r.entityId);
|
|
469
|
-
const
|
|
470
|
-
.from(entity.table)
|
|
471
|
-
.selectAll()
|
|
472
|
-
.where(["id", "=", r.id])
|
|
473
|
-
.first()
|
|
474
|
-
.execute();
|
|
550
|
+
const record = await db(entity.table).where("id", r.id).first();
|
|
475
551
|
records.push({
|
|
476
552
|
entityId: r.entityId,
|
|
477
553
|
data: record,
|
|
@@ -505,10 +581,7 @@ export class FixtureManagerClass {
|
|
|
505
581
|
return insertData;
|
|
506
582
|
}
|
|
507
583
|
|
|
508
|
-
private async insertFixture(
|
|
509
|
-
db: KnexClient | KyselyClient,
|
|
510
|
-
fixture: FixtureRecord
|
|
511
|
-
) {
|
|
584
|
+
private async insertFixture(db: Knex, fixture: FixtureRecord) {
|
|
512
585
|
const insertData = this.prepareInsertData(fixture);
|
|
513
586
|
const entity = EntityManager.get(fixture.entityId);
|
|
514
587
|
|
|
@@ -521,12 +594,7 @@ export class FixtureManagerClass {
|
|
|
521
594
|
};
|
|
522
595
|
}
|
|
523
596
|
|
|
524
|
-
const
|
|
525
|
-
.from(entity.table)
|
|
526
|
-
.select("id")
|
|
527
|
-
.where(["id", "=", fixture.id])
|
|
528
|
-
.first()
|
|
529
|
-
.execute();
|
|
597
|
+
const found = await db(entity.table).where("id", fixture.id).first();
|
|
530
598
|
if (found && !fixture.override) {
|
|
531
599
|
return {
|
|
532
600
|
entityId: fixture.entityId,
|
|
@@ -534,8 +602,8 @@ export class FixtureManagerClass {
|
|
|
534
602
|
};
|
|
535
603
|
}
|
|
536
604
|
|
|
537
|
-
|
|
538
|
-
|
|
605
|
+
const q = db.insert(insertData).into(entity.table);
|
|
606
|
+
await q.onDuplicateUpdate.apply(q, Object.keys(insertData));
|
|
539
607
|
return {
|
|
540
608
|
entityId: fixture.entityId,
|
|
541
609
|
id: fixture.id,
|
|
@@ -547,7 +615,7 @@ export class FixtureManagerClass {
|
|
|
547
615
|
}
|
|
548
616
|
|
|
549
617
|
private async handleManyToManyRelations(
|
|
550
|
-
db:
|
|
618
|
+
db: Knex,
|
|
551
619
|
fixture: FixtureRecord,
|
|
552
620
|
fixtures: FixtureRecord[]
|
|
553
621
|
) {
|
|
@@ -572,29 +640,20 @@ export class FixtureManagerClass {
|
|
|
572
640
|
);
|
|
573
641
|
}
|
|
574
642
|
|
|
575
|
-
const [found] = await db
|
|
576
|
-
.
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
`${inflection.singularize(relatedEntity.table)}_id`,
|
|
582
|
-
"=",
|
|
583
|
-
relatedId,
|
|
584
|
-
],
|
|
585
|
-
])
|
|
586
|
-
.first()
|
|
587
|
-
.execute();
|
|
643
|
+
const [found] = await db(joinTable)
|
|
644
|
+
.where({
|
|
645
|
+
[`${inflection.singularize(entity.table)}_id`]: fixture.id,
|
|
646
|
+
[`${inflection.singularize(relatedEntity.table)}_id`]: relatedId,
|
|
647
|
+
})
|
|
648
|
+
.limit(1);
|
|
588
649
|
if (found) {
|
|
589
650
|
continue;
|
|
590
651
|
}
|
|
591
652
|
|
|
592
|
-
const newIds = await db.insert(
|
|
593
|
-
{
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
},
|
|
597
|
-
]);
|
|
653
|
+
const newIds = await db(joinTable).insert({
|
|
654
|
+
[`${inflection.singularize(entity.table)}_id`]: fixture.id,
|
|
655
|
+
[`${inflection.singularize(relatedEntity.table)}_id`]: relatedId,
|
|
656
|
+
});
|
|
598
657
|
console.log(
|
|
599
658
|
chalk.green(
|
|
600
659
|
`Inserted into ${joinTable}: ${entity.table}(${fixture.id}) - ${relatedEntity.table}(${relatedId}) ID: ${newIds}`
|
|
@@ -628,7 +687,7 @@ export class FixtureManagerClass {
|
|
|
628
687
|
|
|
629
688
|
// 해당 픽스쳐의 값으로 유니크 제약에 위배되는 레코드가 있는지 확인
|
|
630
689
|
private async checkUniqueViolation(
|
|
631
|
-
db:
|
|
690
|
+
db: Knex,
|
|
632
691
|
entity: Entity,
|
|
633
692
|
fixture: FixtureRecord
|
|
634
693
|
) {
|
|
@@ -642,34 +701,30 @@ export class FixtureManagerClass {
|
|
|
642
701
|
return null;
|
|
643
702
|
}
|
|
644
703
|
|
|
645
|
-
let uniqueQuery = db
|
|
646
|
-
const
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
const
|
|
704
|
+
let uniqueQuery = db(entity.table);
|
|
705
|
+
for (const index of uniqueIndexes) {
|
|
706
|
+
// 컬럼 중 하나라도 null이면 유니크 제약을 위반하지 않기 때문에 해당 인덱스는 무시
|
|
707
|
+
const containsNull = index.columns.some((column) => {
|
|
708
|
+
const field = column.split("_id")[0];
|
|
709
|
+
return fixture.columns[field].value === null;
|
|
710
|
+
});
|
|
711
|
+
if (containsNull) {
|
|
712
|
+
continue;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
uniqueQuery = uniqueQuery.orWhere((qb) => {
|
|
716
|
+
for (const column of index.columns) {
|
|
650
717
|
const field = column.split("_id")[0];
|
|
651
|
-
return fixture.columns[field].value === null;
|
|
652
|
-
});
|
|
653
|
-
if (containsNull) {
|
|
654
|
-
return;
|
|
655
|
-
}
|
|
656
718
|
|
|
657
|
-
return index.columns.map((c) => {
|
|
658
|
-
const field = c.split("_id")[0];
|
|
659
719
|
if (Array.isArray(fixture.columns[field].value)) {
|
|
660
|
-
|
|
720
|
+
qb.whereIn(column, fixture.columns[field].value);
|
|
661
721
|
} else {
|
|
662
|
-
|
|
722
|
+
qb.andWhere(column, fixture.columns[field].value);
|
|
663
723
|
}
|
|
664
|
-
}
|
|
665
|
-
})
|
|
666
|
-
.filter(Boolean) as WhereClause[];
|
|
667
|
-
|
|
668
|
-
for (const clauses of whereClauses) {
|
|
669
|
-
uniqueQuery = uniqueQuery.orWhere(clauses);
|
|
724
|
+
}
|
|
725
|
+
});
|
|
670
726
|
}
|
|
671
|
-
|
|
672
|
-
const [uniqueFound] = await uniqueQuery.execute();
|
|
727
|
+
const [uniqueFound] = await uniqueQuery;
|
|
673
728
|
return uniqueFound;
|
|
674
729
|
}
|
|
675
730
|
}
|