@nocobase/database 0.5.0-alpha.37 → 0.7.0-alpha.1
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/LICENSE +201 -21
- package/esm/collection-importer.d.ts +7 -0
- package/esm/collection-importer.js +49 -0
- package/esm/collection-importer.js.map +1 -0
- package/esm/collection.d.ts +73 -0
- package/esm/collection.js +224 -0
- package/esm/collection.js.map +1 -0
- package/esm/database.d.ts +101 -0
- package/esm/database.js +275 -0
- package/esm/database.js.map +1 -0
- package/esm/fields/array-field.d.ts +11 -0
- package/esm/fields/array-field.js +26 -0
- package/esm/fields/array-field.js.map +1 -0
- package/esm/fields/belongs-to-field.d.ts +12 -0
- package/esm/fields/belongs-to-field.js +57 -0
- package/esm/fields/belongs-to-field.js.map +1 -0
- package/esm/fields/belongs-to-many-field.d.ts +11 -0
- package/esm/fields/belongs-to-many-field.js +55 -0
- package/esm/fields/belongs-to-many-field.js.map +1 -0
- package/esm/fields/boolean-field.d.ts +8 -0
- package/esm/fields/boolean-field.js +8 -0
- package/esm/fields/boolean-field.js.map +1 -0
- package/esm/fields/context-field.d.ts +13 -0
- package/esm/fields/context-field.js +43 -0
- package/esm/fields/context-field.js.map +1 -0
- package/esm/fields/date-field.d.ts +8 -0
- package/esm/fields/date-field.js +8 -0
- package/esm/fields/date-field.js.map +1 -0
- package/esm/fields/field.d.ts +37 -0
- package/esm/fields/field.js +74 -0
- package/esm/fields/field.js.map +1 -0
- package/esm/fields/has-inverse-field.d.ts +4 -0
- package/esm/fields/has-inverse-field.js +2 -0
- package/esm/fields/has-inverse-field.js.map +1 -0
- package/esm/fields/has-many-field.d.ts +64 -0
- package/esm/fields/has-many-field.js +58 -0
- package/esm/fields/has-many-field.js.map +1 -0
- package/esm/fields/has-one-field.d.ts +64 -0
- package/esm/fields/has-one-field.js +57 -0
- package/esm/fields/has-one-field.js.map +1 -0
- package/esm/fields/index.d.ts +40 -0
- package/esm/fields/index.js +21 -0
- package/esm/fields/index.js.map +1 -0
- package/esm/fields/json-field.d.ts +14 -0
- package/esm/fields/json-field.js +17 -0
- package/esm/fields/json-field.js.map +1 -0
- package/esm/fields/number-field.d.ts +32 -0
- package/esm/fields/number-field.js +28 -0
- package/esm/fields/number-field.js.map +1 -0
- package/esm/fields/password-field.d.ts +21 -0
- package/esm/fields/password-field.js +71 -0
- package/esm/fields/password-field.js.map +1 -0
- package/esm/fields/radio-field.d.ts +14 -0
- package/esm/fields/radio-field.js +49 -0
- package/esm/fields/radio-field.js.map +1 -0
- package/esm/fields/relation-field.d.ts +20 -0
- package/esm/fields/relation-field.js +27 -0
- package/esm/fields/relation-field.js.map +1 -0
- package/esm/fields/sort-field.d.ts +16 -0
- package/esm/fields/sort-field.js +90 -0
- package/esm/fields/sort-field.js.map +1 -0
- package/esm/fields/string-field.d.ts +8 -0
- package/esm/fields/string-field.js +8 -0
- package/esm/fields/string-field.js.map +1 -0
- package/esm/fields/text-field.d.ts +8 -0
- package/esm/fields/text-field.js +8 -0
- package/esm/fields/text-field.js.map +1 -0
- package/esm/fields/time-field.d.ts +8 -0
- package/esm/fields/time-field.js +8 -0
- package/esm/fields/time-field.js.map +1 -0
- package/esm/fields/uid-field.d.ts +10 -0
- package/esm/fields/uid-field.js +27 -0
- package/esm/fields/uid-field.js.map +1 -0
- package/esm/fields/virtual-field.d.ts +8 -0
- package/esm/fields/virtual-field.js +8 -0
- package/esm/fields/virtual-field.js.map +1 -0
- package/esm/filter-parser.d.ts +27 -0
- package/esm/filter-parser.js +185 -0
- package/esm/filter-parser.js.map +1 -0
- package/esm/index.d.ts +15 -0
- package/esm/index.js +16 -0
- package/esm/index.js.map +1 -0
- package/esm/magic-attribute-model.d.ts +7 -0
- package/esm/magic-attribute-model.js +70 -0
- package/esm/magic-attribute-model.js.map +1 -0
- package/esm/mock-database.d.ts +22 -0
- package/esm/mock-database.js +34 -0
- package/esm/mock-database.js.map +1 -0
- package/esm/model-hook.d.ts +12 -0
- package/esm/model-hook.js +61 -0
- package/esm/model-hook.js.map +1 -0
- package/esm/model.d.ts +15 -0
- package/esm/model.js +80 -0
- package/esm/model.js.map +1 -0
- package/esm/operators/array.d.ts +26 -0
- package/esm/operators/array.js +105 -0
- package/esm/operators/array.js.map +1 -0
- package/esm/operators/association.d.ts +10 -0
- package/esm/operators/association.js +14 -0
- package/esm/operators/association.js.map +1 -0
- package/esm/operators/date.d.ts +34 -0
- package/esm/operators/date.js +35 -0
- package/esm/operators/date.js.map +1 -0
- package/esm/operators/empty.d.ts +28 -0
- package/esm/operators/empty.js +58 -0
- package/esm/operators/empty.js.map +1 -0
- package/esm/operators/index.d.ts +2 -0
- package/esm/operators/index.js +2 -0
- package/esm/operators/index.js.map +1 -0
- package/esm/operators/ne.d.ts +10 -0
- package/esm/operators/ne.js +12 -0
- package/esm/operators/ne.js.map +1 -0
- package/esm/operators/string.d.ts +21 -0
- package/esm/operators/string.js +35 -0
- package/esm/operators/string.js.map +1 -0
- package/esm/operators/utils.d.ts +4 -0
- package/esm/operators/utils.js +11 -0
- package/esm/operators/utils.js.map +1 -0
- package/esm/options-parser.d.ts +31 -0
- package/esm/options-parser.js +225 -0
- package/esm/options-parser.js.map +1 -0
- package/esm/playground.d.ts +1 -0
- package/esm/playground.js +53 -0
- package/esm/playground.js.map +1 -0
- package/esm/relation-repository/belongs-to-many-repository.d.ts +36 -0
- package/esm/relation-repository/belongs-to-many-repository.js +199 -0
- package/esm/relation-repository/belongs-to-many-repository.js.map +1 -0
- package/esm/relation-repository/belongs-to-repository.d.ts +17 -0
- package/esm/relation-repository/belongs-to-repository.js +4 -0
- package/esm/relation-repository/belongs-to-repository.js.map +1 -0
- package/esm/relation-repository/hasmany-repository.d.ts +23 -0
- package/esm/relation-repository/hasmany-repository.js +125 -0
- package/esm/relation-repository/hasmany-repository.js.map +1 -0
- package/esm/relation-repository/hasone-repository.d.ts +17 -0
- package/esm/relation-repository/hasone-repository.js +4 -0
- package/esm/relation-repository/hasone-repository.js.map +1 -0
- package/esm/relation-repository/multiple-relation-repository.d.ts +23 -0
- package/esm/relation-repository/multiple-relation-repository.js +149 -0
- package/esm/relation-repository/multiple-relation-repository.js.map +1 -0
- package/esm/relation-repository/relation-repository.d.ts +32 -0
- package/esm/relation-repository/relation-repository.js +93 -0
- package/esm/relation-repository/relation-repository.js.map +1 -0
- package/esm/relation-repository/single-relation-repository.d.ts +23 -0
- package/esm/relation-repository/single-relation-repository.js +96 -0
- package/esm/relation-repository/single-relation-repository.js.map +1 -0
- package/esm/relation-repository/types.d.ts +7 -0
- package/esm/relation-repository/types.js +2 -0
- package/esm/relation-repository/types.js.map +1 -0
- package/esm/repository.d.ts +165 -0
- package/esm/repository.js +276 -0
- package/esm/repository.js.map +1 -0
- package/esm/transaction-decorator.d.ts +1 -0
- package/esm/transaction-decorator.js +63 -0
- package/esm/transaction-decorator.js.map +1 -0
- package/esm/update-associations.d.ts +60 -0
- package/esm/update-associations.js +362 -0
- package/esm/update-associations.js.map +1 -0
- package/esm/update-guard.d.ts +26 -0
- package/esm/update-guard.js +122 -0
- package/esm/update-guard.js.map +1 -0
- package/lib/collection-importer.d.ts +7 -0
- package/lib/collection-importer.js +75 -0
- package/lib/collection-importer.js.map +1 -0
- package/lib/collection.d.ts +73 -0
- package/lib/collection.js +231 -0
- package/lib/collection.js.map +1 -0
- package/lib/database.d.ts +93 -43
- package/lib/database.js +277 -471
- package/lib/database.js.map +1 -1
- package/lib/fields/array-field.d.ts +11 -0
- package/lib/fields/array-field.js +30 -0
- package/lib/fields/array-field.js.map +1 -0
- package/lib/fields/belongs-to-field.d.ts +12 -0
- package/lib/fields/belongs-to-field.js +61 -0
- package/lib/fields/belongs-to-field.js.map +1 -0
- package/lib/fields/belongs-to-many-field.d.ts +11 -0
- package/lib/fields/belongs-to-many-field.js +59 -0
- package/lib/fields/belongs-to-many-field.js.map +1 -0
- package/lib/fields/boolean-field.d.ts +8 -0
- package/lib/fields/boolean-field.js +12 -0
- package/lib/fields/boolean-field.js.map +1 -0
- package/lib/fields/context-field.d.ts +13 -0
- package/lib/fields/context-field.js +47 -0
- package/lib/fields/context-field.js.map +1 -0
- package/lib/fields/date-field.d.ts +8 -0
- package/lib/fields/date-field.js +12 -0
- package/lib/fields/date-field.js.map +1 -0
- package/lib/fields/field.d.ts +37 -0
- package/lib/fields/field.js +81 -0
- package/lib/fields/field.js.map +1 -0
- package/lib/fields/has-inverse-field.d.ts +4 -0
- package/lib/fields/has-inverse-field.js +3 -0
- package/lib/fields/has-inverse-field.js.map +1 -0
- package/lib/fields/has-many-field.d.ts +64 -0
- package/lib/fields/has-many-field.js +62 -0
- package/lib/fields/has-many-field.js.map +1 -0
- package/lib/fields/has-one-field.d.ts +64 -0
- package/lib/fields/has-one-field.js +61 -0
- package/lib/fields/has-one-field.js.map +1 -0
- package/lib/fields/index.d.ts +40 -10
- package/lib/fields/index.js +31 -138
- package/lib/fields/index.js.map +1 -1
- package/lib/fields/json-field.d.ts +14 -0
- package/lib/fields/json-field.js +22 -0
- package/lib/fields/json-field.js.map +1 -0
- package/lib/fields/number-field.d.ts +32 -0
- package/lib/fields/number-field.js +36 -0
- package/lib/fields/number-field.js.map +1 -0
- package/lib/fields/password-field.d.ts +21 -0
- package/lib/fields/password-field.js +78 -0
- package/lib/fields/password-field.js.map +1 -0
- package/lib/fields/radio-field.d.ts +14 -0
- package/lib/fields/radio-field.js +53 -0
- package/lib/fields/radio-field.js.map +1 -0
- package/lib/fields/relation-field.d.ts +20 -0
- package/lib/fields/relation-field.js +31 -0
- package/lib/fields/relation-field.js.map +1 -0
- package/lib/fields/sort-field.d.ts +16 -0
- package/lib/fields/sort-field.js +94 -0
- package/lib/fields/sort-field.js.map +1 -0
- package/lib/fields/string-field.d.ts +8 -0
- package/lib/fields/string-field.js +12 -0
- package/lib/fields/string-field.js.map +1 -0
- package/lib/fields/text-field.d.ts +8 -0
- package/lib/fields/text-field.js +12 -0
- package/lib/fields/text-field.js.map +1 -0
- package/lib/fields/time-field.d.ts +8 -0
- package/lib/fields/time-field.js +12 -0
- package/lib/fields/time-field.js.map +1 -0
- package/lib/fields/uid-field.d.ts +10 -0
- package/lib/fields/uid-field.js +31 -0
- package/lib/fields/uid-field.js.map +1 -0
- package/lib/fields/virtual-field.d.ts +8 -0
- package/lib/fields/virtual-field.js +12 -0
- package/lib/fields/virtual-field.js.map +1 -0
- package/lib/filter-parser.d.ts +27 -0
- package/lib/filter-parser.js +191 -0
- package/lib/filter-parser.js.map +1 -0
- package/lib/index.d.ts +13 -6
- package/lib/index.js +27 -60
- package/lib/index.js.map +1 -1
- package/lib/magic-attribute-model.d.ts +7 -0
- package/lib/magic-attribute-model.js +77 -0
- package/lib/magic-attribute-model.js.map +1 -0
- package/lib/mock-database.d.ts +22 -0
- package/lib/mock-database.js +40 -0
- package/lib/mock-database.js.map +1 -0
- package/lib/model-hook.d.ts +12 -0
- package/lib/model-hook.js +68 -0
- package/lib/model-hook.js.map +1 -0
- package/lib/model.d.ts +11 -45
- package/lib/model.js +76 -452
- package/lib/model.js.map +1 -1
- package/lib/operators/array.d.ts +26 -0
- package/lib/operators/array.js +107 -0
- package/lib/operators/array.js.map +1 -0
- package/lib/operators/association.d.ts +10 -0
- package/lib/operators/association.js +16 -0
- package/lib/operators/association.js.map +1 -0
- package/lib/operators/date.d.ts +34 -0
- package/lib/operators/date.js +40 -0
- package/lib/operators/date.js.map +1 -0
- package/lib/operators/empty.d.ts +28 -0
- package/lib/operators/empty.js +82 -0
- package/lib/operators/empty.js.map +1 -0
- package/lib/operators/index.d.ts +2 -0
- package/lib/operators/index.js +4 -0
- package/lib/operators/index.js.map +1 -0
- package/lib/operators/ne.d.ts +10 -0
- package/lib/operators/ne.js +14 -0
- package/lib/operators/ne.js.map +1 -0
- package/lib/operators/string.d.ts +21 -0
- package/lib/operators/string.js +37 -0
- package/lib/operators/string.js.map +1 -0
- package/lib/operators/utils.d.ts +4 -0
- package/lib/operators/utils.js +16 -0
- package/lib/operators/utils.js.map +1 -0
- package/lib/options-parser.d.ts +31 -0
- package/lib/options-parser.js +232 -0
- package/lib/options-parser.js.map +1 -0
- package/lib/playground.d.ts +1 -0
- package/lib/playground.js +55 -0
- package/lib/playground.js.map +1 -0
- package/lib/relation-repository/belongs-to-many-repository.d.ts +36 -0
- package/lib/relation-repository/belongs-to-many-repository.js +206 -0
- package/lib/relation-repository/belongs-to-many-repository.js.map +1 -0
- package/lib/relation-repository/belongs-to-repository.d.ts +17 -0
- package/lib/relation-repository/belongs-to-repository.js +8 -0
- package/lib/relation-repository/belongs-to-repository.js.map +1 -0
- package/lib/relation-repository/hasmany-repository.d.ts +23 -0
- package/lib/relation-repository/hasmany-repository.js +129 -0
- package/lib/relation-repository/hasmany-repository.js.map +1 -0
- package/lib/relation-repository/hasone-repository.d.ts +17 -0
- package/lib/relation-repository/hasone-repository.js +8 -0
- package/lib/relation-repository/hasone-repository.js.map +1 -0
- package/lib/relation-repository/multiple-relation-repository.d.ts +23 -0
- package/lib/relation-repository/multiple-relation-repository.js +153 -0
- package/lib/relation-repository/multiple-relation-repository.js.map +1 -0
- package/lib/relation-repository/relation-repository.d.ts +32 -0
- package/lib/relation-repository/relation-repository.js +100 -0
- package/lib/relation-repository/relation-repository.js.map +1 -0
- package/lib/relation-repository/single-relation-repository.d.ts +23 -0
- package/lib/relation-repository/single-relation-repository.js +103 -0
- package/lib/relation-repository/single-relation-repository.js.map +1 -0
- package/lib/relation-repository/types.d.ts +7 -0
- package/lib/relation-repository/types.js +3 -0
- package/lib/relation-repository/types.js.map +1 -0
- package/lib/repository.d.ts +165 -0
- package/lib/repository.js +302 -0
- package/lib/repository.js.map +1 -0
- package/lib/transaction-decorator.d.ts +1 -0
- package/lib/transaction-decorator.js +70 -0
- package/lib/transaction-decorator.js.map +1 -0
- package/lib/update-associations.d.ts +60 -0
- package/lib/update-associations.js +374 -0
- package/lib/update-associations.js.map +1 -0
- package/lib/update-guard.d.ts +26 -0
- package/lib/update-guard.js +129 -0
- package/lib/update-guard.js.map +1 -0
- package/package.json +17 -5
- package/src/__tests__/collection-importer.test.ts +21 -0
- package/src/__tests__/collection.sortable.test.ts +65 -0
- package/src/__tests__/collection.test.ts +218 -0
- package/src/__tests__/database.import.test.ts +33 -0
- package/src/__tests__/database.test.ts +229 -0
- package/src/__tests__/field-options/hidden.test.ts +302 -0
- package/src/__tests__/field-options/sort-by.test.ts +220 -0
- package/src/__tests__/fields/belongs-to-field.test.ts +162 -0
- package/src/__tests__/fields/belongs-to-many-field.test.ts +61 -0
- package/src/__tests__/fields/context-field.test.ts +140 -0
- package/src/__tests__/fields/has-many-field.test.ts +152 -0
- package/src/__tests__/fields/has-one-field.test.ts +67 -0
- package/src/__tests__/fields/password-field.test.ts +30 -0
- package/src/__tests__/fields/sort-field.test.ts +133 -0
- package/src/__tests__/fields/string-field.test.ts +77 -0
- package/src/__tests__/filter-parser.test.ts +104 -0
- package/src/__tests__/fixtures/c0/a.ts +6 -0
- package/src/__tests__/fixtures/c1/b.ts +6 -0
- package/src/__tests__/fixtures/c2/a.ts +6 -0
- package/src/__tests__/fixtures/collections/delay-extend.ts +6 -0
- package/src/__tests__/fixtures/collections/delay-extend2.ts +6 -0
- package/src/__tests__/fixtures/collections/extend.ts +6 -0
- package/src/__tests__/fixtures/collections/extend2.ts +6 -0
- package/src/__tests__/fixtures/collections/posts.ts +4 -0
- package/src/__tests__/fixtures/collections/tags.js +4 -0
- package/src/__tests__/fixtures/collections/test.jpg +0 -0
- package/src/__tests__/fixtures/collections/user.json +9 -0
- package/src/__tests__/index.ts +1 -0
- package/src/__tests__/magic-attribute-model.test.ts +103 -0
- package/src/__tests__/model.test.ts +60 -0
- package/src/__tests__/operator/array-operator.test.ts +268 -0
- package/src/__tests__/operator/association-operator.test.ts +263 -0
- package/src/__tests__/operator/date-operator.test.ts +165 -0
- package/src/__tests__/operator/empty-operator.test.ts +77 -0
- package/src/__tests__/operator/ne.test.ts +33 -0
- package/src/__tests__/operator/string-operator.test.ts +62 -0
- package/src/__tests__/option-parser.test.ts +185 -0
- package/src/__tests__/relation-repository/belongs-to-many-repository.test.ts +697 -0
- package/src/__tests__/relation-repository/has-many-repository.test.ts +414 -0
- package/src/__tests__/relation-repository/hasone-repository.test.ts +77 -0
- package/src/__tests__/repository/count.test.ts +180 -0
- package/src/__tests__/repository/create.test.ts +163 -0
- package/src/__tests__/repository/destroy.test.ts +196 -0
- package/src/__tests__/repository/find.test.ts +247 -0
- package/src/__tests__/repository/update.test.ts +60 -0
- package/src/__tests__/repository.test.ts +438 -0
- package/src/__tests__/update-associations.test.ts +412 -0
- package/src/__tests__/update-guard.test.ts +376 -0
- package/src/collection-importer.ts +49 -0
- package/src/collection.ts +282 -0
- package/src/database.ts +340 -0
- package/src/fields/array-field.ts +35 -0
- package/src/fields/belongs-to-field.ts +76 -0
- package/src/fields/belongs-to-many-field.ts +77 -0
- package/src/fields/boolean-field.ts +12 -0
- package/src/fields/context-field.ts +45 -0
- package/src/fields/date-field.ts +12 -0
- package/src/fields/field.ts +105 -0
- package/src/fields/has-inverse-field.ts +5 -0
- package/src/fields/has-many-field.ts +143 -0
- package/src/fields/has-one-field.ts +136 -0
- package/src/fields/index.ts +72 -0
- package/src/fields/json-field.ts +25 -0
- package/src/fields/number-field.ts +52 -0
- package/src/fields/password-field.ts +72 -0
- package/src/fields/radio-field.ts +50 -0
- package/src/fields/relation-field.ts +37 -0
- package/src/fields/sort-field.ts +96 -0
- package/src/fields/string-field.ts +12 -0
- package/src/fields/text-field.ts +12 -0
- package/src/fields/time-field.ts +12 -0
- package/src/fields/uid-field.ts +24 -0
- package/src/fields/virtual-field.ts +12 -0
- package/src/filter-parser.ts +243 -0
- package/src/index.ts +16 -0
- package/src/magic-attribute-model.ts +62 -0
- package/src/mock-database.ts +42 -0
- package/src/model-hook.ts +69 -0
- package/src/model.ts +114 -0
- package/src/operators/array.ts +145 -0
- package/src/operators/association.ts +14 -0
- package/src/operators/date.ts +41 -0
- package/src/operators/empty.ts +75 -0
- package/src/operators/index.ts +8 -0
- package/src/operators/ne.ts +12 -0
- package/src/operators/string.ts +40 -0
- package/src/operators/utils.ts +13 -0
- package/src/options-parser.ts +285 -0
- package/src/playground.ts +52 -0
- package/src/relation-repository/belongs-to-many-repository.ts +240 -0
- package/src/relation-repository/belongs-to-repository.ts +23 -0
- package/src/relation-repository/hasmany-repository.ts +145 -0
- package/src/relation-repository/hasone-repository.ts +23 -0
- package/src/relation-repository/multiple-relation-repository.ts +198 -0
- package/src/relation-repository/relation-repository.ts +114 -0
- package/src/relation-repository/single-relation-repository.ts +99 -0
- package/src/relation-repository/types.ts +15 -0
- package/src/repository.ts +478 -0
- package/src/transaction-decorator.ts +58 -0
- package/src/update-associations.ts +478 -0
- package/src/update-guard.ts +167 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.json +5 -0
- package/examples/index.ts +0 -125
- package/examples/plugins/db-driven/index.ts +0 -25
- package/examples/plugins/db-driven/tables/fields.ts +0 -78
- package/examples/plugins/db-driven/tables/tables.ts +0 -53
- package/examples/tables/bar.js +0 -26
- package/examples/tables/comments.ts +0 -19
- package/examples/tables/foo.json +0 -3
- package/examples/tables/posts.ts +0 -28
- package/examples/tables/profiles.ts +0 -23
- package/examples/tables/tags.ts +0 -15
- package/examples/tables/users.ts +0 -34
- package/lib/database.d.ts.map +0 -1
- package/lib/fields/field-types.d.ts +0 -419
- package/lib/fields/field-types.d.ts.map +0 -1
- package/lib/fields/field-types.js +0 -1222
- package/lib/fields/field-types.js.map +0 -1
- package/lib/fields/index.d.ts.map +0 -1
- package/lib/fields/option-types.d.ts +0 -105
- package/lib/fields/option-types.d.ts.map +0 -1
- package/lib/fields/option-types.js +0 -18
- package/lib/fields/option-types.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/model.d.ts.map +0 -1
- package/lib/op.d.ts +0 -45
- package/lib/op.d.ts.map +0 -1
- package/lib/op.js +0 -225
- package/lib/op.js.map +0 -1
- package/lib/table.d.ts +0 -56
- package/lib/table.d.ts.map +0 -1
- package/lib/table.js +0 -456
- package/lib/table.js.map +0 -1
- package/lib/utils.d.ts +0 -26
- package/lib/utils.d.ts.map +0 -1
- package/lib/utils.js +0 -438
- package/lib/utils.js.map +0 -1
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import lodash from 'lodash';
|
|
2
|
+
import { Association, BelongsTo, BelongsToMany, HasMany, HasOne, ModelCtor, Transaction } from 'sequelize';
|
|
3
|
+
import { Collection } from '../collection';
|
|
4
|
+
import Database from '../database';
|
|
5
|
+
import { RelationField } from '../fields/relation-field';
|
|
6
|
+
import FilterParser from '../filter-parser';
|
|
7
|
+
import { Model } from '../model';
|
|
8
|
+
import { OptionsParser } from '../options-parser';
|
|
9
|
+
import { CreateOptions, Filter, FindOptions } from '../repository';
|
|
10
|
+
import { transactionWrapperBuilder } from '../transaction-decorator';
|
|
11
|
+
import { updateAssociations } from '../update-associations';
|
|
12
|
+
import { UpdateGuard } from '../update-guard';
|
|
13
|
+
|
|
14
|
+
export const transaction = transactionWrapperBuilder(function () {
|
|
15
|
+
return this.sourceCollection.model.sequelize.transaction();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export abstract class RelationRepository {
|
|
19
|
+
sourceCollection: Collection;
|
|
20
|
+
association: Association;
|
|
21
|
+
targetModel: ModelCtor<any>;
|
|
22
|
+
targetCollection: Collection;
|
|
23
|
+
associationName: string;
|
|
24
|
+
associationField: RelationField;
|
|
25
|
+
sourceKeyValue: string | number;
|
|
26
|
+
sourceInstance: Model;
|
|
27
|
+
db: Database;
|
|
28
|
+
|
|
29
|
+
constructor(sourceCollection: Collection, association: string, sourceKeyValue: string | number) {
|
|
30
|
+
this.db = sourceCollection.context.database;
|
|
31
|
+
|
|
32
|
+
this.sourceCollection = sourceCollection;
|
|
33
|
+
this.sourceKeyValue = sourceKeyValue;
|
|
34
|
+
this.associationName = association;
|
|
35
|
+
this.association = this.sourceCollection.model.associations[association];
|
|
36
|
+
|
|
37
|
+
this.associationField = this.sourceCollection.getField(association);
|
|
38
|
+
|
|
39
|
+
this.targetModel = this.association.target;
|
|
40
|
+
this.targetCollection = this.sourceCollection.context.database.modelCollection.get(this.targetModel);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
targetKey() {
|
|
44
|
+
return this.associationField.targetKey;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
protected accessors() {
|
|
48
|
+
return (<BelongsTo | HasOne | HasMany | BelongsToMany>this.association).accessors;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async create(options?: CreateOptions): Promise<any> {
|
|
52
|
+
const createAccessor = this.accessors().create;
|
|
53
|
+
|
|
54
|
+
const guard = UpdateGuard.fromOptions(this.targetModel, options);
|
|
55
|
+
const values = options.values;
|
|
56
|
+
|
|
57
|
+
const sourceModel = await this.getSourceModel();
|
|
58
|
+
|
|
59
|
+
const instance = await sourceModel[createAccessor](guard.sanitize(options.values), options);
|
|
60
|
+
|
|
61
|
+
await updateAssociations(instance, values, options);
|
|
62
|
+
|
|
63
|
+
if (options.hooks !== false) {
|
|
64
|
+
await this.db.emitAsync(`${this.targetCollection.name}.afterCreateWithAssociations`, instance, options);
|
|
65
|
+
const eventName = `${this.targetCollection.name}.afterSaveWithAssociations`;
|
|
66
|
+
await this.db.emitAsync(eventName, instance, options);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return instance;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async getSourceModel(transaction?: any) {
|
|
73
|
+
if (!this.sourceInstance) {
|
|
74
|
+
this.sourceInstance = await this.sourceCollection.model.findOne({
|
|
75
|
+
where: {
|
|
76
|
+
[this.associationField.sourceKey]: this.sourceKeyValue,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return this.sourceInstance;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
protected buildQueryOptions(options: FindOptions) {
|
|
85
|
+
const parser = new OptionsParser(options, {
|
|
86
|
+
collection: this.targetCollection,
|
|
87
|
+
targetKey: this.targetKey(),
|
|
88
|
+
});
|
|
89
|
+
const params = parser.toSequelizeParams();
|
|
90
|
+
return { ...options, ...params };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
protected parseFilter(filter: Filter, options?: any) {
|
|
94
|
+
const parser = new FilterParser(filter, {
|
|
95
|
+
collection: this.targetCollection,
|
|
96
|
+
app: {
|
|
97
|
+
ctx: options?.context,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
return parser.toSequelizeParams();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
protected async getTransaction(options: any, autoGen = false): Promise<Transaction | null> {
|
|
104
|
+
if (lodash.isPlainObject(options) && options.transaction) {
|
|
105
|
+
return options.transaction;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (autoGen) {
|
|
109
|
+
return await this.sourceCollection.model.sequelize.transaction();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import lodash from 'lodash';
|
|
2
|
+
import { SingleAssociationAccessors } from 'sequelize';
|
|
3
|
+
import { Model } from '../model';
|
|
4
|
+
import { Appends, Except, Fields, Filter, TargetKey, TransactionAble, UpdateOptions } from '../repository';
|
|
5
|
+
import { updateModelByValues } from '../update-associations';
|
|
6
|
+
import { RelationRepository, transaction } from './relation-repository';
|
|
7
|
+
|
|
8
|
+
export interface SingleRelationFindOption extends TransactionAble {
|
|
9
|
+
fields?: Fields;
|
|
10
|
+
except?: Except;
|
|
11
|
+
appends?: Appends;
|
|
12
|
+
filter?: Filter;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface SetOption extends TransactionAble {
|
|
16
|
+
tk?: TargetKey;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export abstract class SingleRelationRepository extends RelationRepository {
|
|
20
|
+
@transaction()
|
|
21
|
+
async remove(options?: TransactionAble): Promise<void> {
|
|
22
|
+
const transaction = await this.getTransaction(options);
|
|
23
|
+
const sourceModel = await this.getSourceModel(transaction);
|
|
24
|
+
return await sourceModel[this.accessors().set](null, {
|
|
25
|
+
transaction,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@transaction((args, transaction) => {
|
|
30
|
+
return {
|
|
31
|
+
tk: args[0],
|
|
32
|
+
transaction,
|
|
33
|
+
};
|
|
34
|
+
})
|
|
35
|
+
async set(options: TargetKey | SetOption): Promise<void> {
|
|
36
|
+
const transaction = await this.getTransaction(options);
|
|
37
|
+
let handleKey = lodash.isPlainObject(options) ? (<SetOption>options).tk : options;
|
|
38
|
+
|
|
39
|
+
const sourceModel = await this.getSourceModel(transaction);
|
|
40
|
+
|
|
41
|
+
return await sourceModel[this.accessors().set](handleKey, {
|
|
42
|
+
transaction,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async find(options?: SingleRelationFindOption): Promise<Model<any>> {
|
|
47
|
+
const transaction = await this.getTransaction(options);
|
|
48
|
+
const findOptions = this.buildQueryOptions({
|
|
49
|
+
...options,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const getAccessor = this.accessors().get;
|
|
53
|
+
const sourceModel = await this.getSourceModel(transaction);
|
|
54
|
+
|
|
55
|
+
return await sourceModel[getAccessor]({
|
|
56
|
+
...findOptions,
|
|
57
|
+
transaction,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async findOne(options?: SingleRelationFindOption): Promise<Model<any>> {
|
|
62
|
+
return this.find(options);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@transaction()
|
|
66
|
+
async destroy(options?: TransactionAble): Promise<Boolean> {
|
|
67
|
+
const transaction = await this.getTransaction(options);
|
|
68
|
+
|
|
69
|
+
const target = await this.find({
|
|
70
|
+
transaction,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
await target.destroy({
|
|
74
|
+
transaction,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@transaction()
|
|
81
|
+
async update(options: UpdateOptions): Promise<any> {
|
|
82
|
+
const transaction = await this.getTransaction(options);
|
|
83
|
+
|
|
84
|
+
const target = await this.find({
|
|
85
|
+
transaction,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
await updateModelByValues(target, options?.values, {
|
|
89
|
+
...lodash.omit(options, 'values'),
|
|
90
|
+
transaction,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
return target;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
accessors() {
|
|
97
|
+
return <SingleAssociationAccessors>super.accessors();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { TargetKey, Values } from '../repository';
|
|
2
|
+
import { Transactionable } from 'sequelize';
|
|
3
|
+
|
|
4
|
+
export type PrimaryKeyWithThroughValues = [TargetKey, Values];
|
|
5
|
+
|
|
6
|
+
export interface AssociatedOptions extends Transactionable {
|
|
7
|
+
tk?: TargetKey | TargetKey[] | PrimaryKeyWithThroughValues | PrimaryKeyWithThroughValues[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type setAssociationOptions =
|
|
11
|
+
| TargetKey
|
|
12
|
+
| TargetKey[]
|
|
13
|
+
| PrimaryKeyWithThroughValues
|
|
14
|
+
| PrimaryKeyWithThroughValues[]
|
|
15
|
+
| AssociatedOptions;
|
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
import lodash, { omit } from 'lodash';
|
|
2
|
+
import {
|
|
3
|
+
Association,
|
|
4
|
+
BulkCreateOptions,
|
|
5
|
+
CreateOptions as SequelizeCreateOptions,
|
|
6
|
+
DestroyOptions as SequelizeDestroyOptions,
|
|
7
|
+
FindAndCountOptions as SequelizeAndCountOptions,
|
|
8
|
+
FindOptions as SequelizeFindOptions,
|
|
9
|
+
ModelCtor,
|
|
10
|
+
Op,
|
|
11
|
+
Transaction,
|
|
12
|
+
UpdateOptions as SequelizeUpdateOptions
|
|
13
|
+
} from 'sequelize';
|
|
14
|
+
import { Collection } from './collection';
|
|
15
|
+
import { Database } from './database';
|
|
16
|
+
import { RelationField } from './fields';
|
|
17
|
+
import FilterParser from './filter-parser';
|
|
18
|
+
import { Model } from './model';
|
|
19
|
+
import { OptionsParser } from './options-parser';
|
|
20
|
+
import { BelongsToManyRepository } from './relation-repository/belongs-to-many-repository';
|
|
21
|
+
import { BelongsToRepository } from './relation-repository/belongs-to-repository';
|
|
22
|
+
import { HasManyRepository } from './relation-repository/hasmany-repository';
|
|
23
|
+
import { HasOneRepository } from './relation-repository/hasone-repository';
|
|
24
|
+
import { RelationRepository } from './relation-repository/relation-repository';
|
|
25
|
+
import { transactionWrapperBuilder } from './transaction-decorator';
|
|
26
|
+
import { updateAssociations, updateModelByValues } from './update-associations';
|
|
27
|
+
import { UpdateGuard } from './update-guard';
|
|
28
|
+
|
|
29
|
+
const debug = require('debug')('noco-database');
|
|
30
|
+
|
|
31
|
+
export interface IRepository {}
|
|
32
|
+
|
|
33
|
+
interface CreateManyOptions extends BulkCreateOptions {
|
|
34
|
+
records: Values[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface TransactionAble {
|
|
38
|
+
transaction?: Transaction;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface FilterAble {
|
|
42
|
+
filter: Filter;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type TargetKey = string | number;
|
|
46
|
+
export type TK = TargetKey | TargetKey[];
|
|
47
|
+
|
|
48
|
+
export type Filter = any;
|
|
49
|
+
export type Appends = string[];
|
|
50
|
+
export type Except = string[];
|
|
51
|
+
export type Fields = string[];
|
|
52
|
+
export type Sort = string[] | string;
|
|
53
|
+
|
|
54
|
+
export type WhiteList = string[];
|
|
55
|
+
export type BlackList = string[];
|
|
56
|
+
export type AssociationKeysToBeUpdate = string[];
|
|
57
|
+
|
|
58
|
+
export type Values = any;
|
|
59
|
+
|
|
60
|
+
export interface CountOptions extends Omit<SequelizeCreateOptions, 'distinct' | 'where' | 'include'>, TransactionAble {
|
|
61
|
+
fields?: Fields;
|
|
62
|
+
filter?: Filter;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface FilterByTk {
|
|
66
|
+
filterByTk?: TargetKey;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface FindOptions extends SequelizeFindOptions, CommonFindOptions, FilterByTk {}
|
|
70
|
+
|
|
71
|
+
export interface CommonFindOptions {
|
|
72
|
+
filter?: Filter;
|
|
73
|
+
fields?: Fields;
|
|
74
|
+
appends?: Appends;
|
|
75
|
+
except?: Except;
|
|
76
|
+
sort?: Sort;
|
|
77
|
+
context?: any;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
interface FindOneOptions extends FindOptions, CommonFindOptions {}
|
|
81
|
+
|
|
82
|
+
export interface DestroyOptions extends SequelizeDestroyOptions {
|
|
83
|
+
filter?: Filter;
|
|
84
|
+
filterByTk?: TargetKey | TargetKey[];
|
|
85
|
+
truncate?: boolean;
|
|
86
|
+
context?: any;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
interface FindAndCountOptions extends Omit<SequelizeAndCountOptions, 'where' | 'include' | 'order'> {
|
|
90
|
+
// 数据过滤
|
|
91
|
+
filter?: Filter;
|
|
92
|
+
// 输出结果显示哪些字段
|
|
93
|
+
fields?: Fields;
|
|
94
|
+
// 输出结果不显示哪些字段
|
|
95
|
+
except?: Except;
|
|
96
|
+
// 附加字段,用于控制关系字段的输出
|
|
97
|
+
appends?: Appends;
|
|
98
|
+
// 排序,字段前面加上 “-” 表示降序
|
|
99
|
+
sort?: Sort;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface CreateOptions extends SequelizeCreateOptions {
|
|
103
|
+
values?: Values;
|
|
104
|
+
whitelist?: WhiteList;
|
|
105
|
+
blacklist?: BlackList;
|
|
106
|
+
updateAssociationValues?: AssociationKeysToBeUpdate;
|
|
107
|
+
context?: any;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface UpdateOptions extends Omit<SequelizeUpdateOptions, 'where'> {
|
|
111
|
+
values: Values;
|
|
112
|
+
filter?: Filter;
|
|
113
|
+
filterByTk?: TargetKey;
|
|
114
|
+
whitelist?: WhiteList;
|
|
115
|
+
blacklist?: BlackList;
|
|
116
|
+
updateAssociationValues?: AssociationKeysToBeUpdate;
|
|
117
|
+
context?: any;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
interface RelatedQueryOptions {
|
|
121
|
+
database: Database;
|
|
122
|
+
field: RelationField;
|
|
123
|
+
source: {
|
|
124
|
+
idOrInstance: any;
|
|
125
|
+
collection: Collection;
|
|
126
|
+
};
|
|
127
|
+
target: {
|
|
128
|
+
association: Association & {
|
|
129
|
+
accessors: any;
|
|
130
|
+
};
|
|
131
|
+
collection: Collection;
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const transaction = transactionWrapperBuilder(function () {
|
|
136
|
+
return (<Repository>this).collection.model.sequelize.transaction();
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
class RelationRepositoryBuilder<R extends RelationRepository> {
|
|
140
|
+
collection: Collection;
|
|
141
|
+
associationName: string;
|
|
142
|
+
association: Association;
|
|
143
|
+
|
|
144
|
+
builderMap = {
|
|
145
|
+
HasOne: HasOneRepository,
|
|
146
|
+
BelongsTo: BelongsToRepository,
|
|
147
|
+
BelongsToMany: BelongsToManyRepository,
|
|
148
|
+
HasMany: HasManyRepository,
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
constructor(collection: Collection, associationName: string) {
|
|
152
|
+
this.collection = collection;
|
|
153
|
+
this.associationName = associationName;
|
|
154
|
+
this.association = this.collection.model.associations[this.associationName];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
protected builder() {
|
|
158
|
+
return this.builderMap;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
of(id: string | number): R {
|
|
162
|
+
const klass = this.builder()[this.association.associationType];
|
|
163
|
+
return new klass(this.collection, this.associationName, id);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export class Repository<TModelAttributes extends {} = any, TCreationAttributes extends {} = TModelAttributes>
|
|
168
|
+
implements IRepository
|
|
169
|
+
{
|
|
170
|
+
database: Database;
|
|
171
|
+
collection: Collection;
|
|
172
|
+
model: ModelCtor<Model>;
|
|
173
|
+
|
|
174
|
+
constructor(collection: Collection) {
|
|
175
|
+
this.database = collection.context.database;
|
|
176
|
+
this.collection = collection;
|
|
177
|
+
this.model = collection.model;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* return count by filter
|
|
182
|
+
*/
|
|
183
|
+
async count(countOptions?: CountOptions): Promise<number> {
|
|
184
|
+
let options = countOptions ? lodash.clone(countOptions) : {};
|
|
185
|
+
|
|
186
|
+
const transaction = await this.getTransaction(options);
|
|
187
|
+
|
|
188
|
+
if (countOptions?.filter) {
|
|
189
|
+
options = {
|
|
190
|
+
...options,
|
|
191
|
+
...this.parseFilter(countOptions.filter, countOptions),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const count = await this.collection.model.count({
|
|
196
|
+
...options,
|
|
197
|
+
distinct: true,
|
|
198
|
+
transaction,
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
return count;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* find
|
|
206
|
+
* @param options
|
|
207
|
+
*/
|
|
208
|
+
async find(options?: FindOptions) {
|
|
209
|
+
const model = this.collection.model;
|
|
210
|
+
const transaction = await this.getTransaction(options);
|
|
211
|
+
|
|
212
|
+
const opts = {
|
|
213
|
+
subQuery: false,
|
|
214
|
+
...this.buildQueryOptions(options),
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
if (opts.include && opts.include.length > 0) {
|
|
218
|
+
// @ts-ignore
|
|
219
|
+
const primaryKeyField = model.primaryKeyField || model.primaryKeyAttribute;
|
|
220
|
+
|
|
221
|
+
const ids = (
|
|
222
|
+
await model.findAll({
|
|
223
|
+
...opts,
|
|
224
|
+
includeIgnoreAttributes: false,
|
|
225
|
+
attributes: [primaryKeyField],
|
|
226
|
+
group: `${model.name}.${primaryKeyField}`,
|
|
227
|
+
transaction,
|
|
228
|
+
})
|
|
229
|
+
).map((row) => row.get(primaryKeyField));
|
|
230
|
+
|
|
231
|
+
const where = {
|
|
232
|
+
[primaryKeyField]: {
|
|
233
|
+
[Op.in]: ids,
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
return await model.findAll({
|
|
238
|
+
...omit(opts, ['limit', 'offset']),
|
|
239
|
+
where,
|
|
240
|
+
transaction,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return await model.findAll({
|
|
245
|
+
...opts,
|
|
246
|
+
transaction,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* find and count
|
|
252
|
+
* @param options
|
|
253
|
+
*/
|
|
254
|
+
async findAndCount(options?: FindAndCountOptions): Promise<[Model[], number]> {
|
|
255
|
+
const transaction = await this.getTransaction(options);
|
|
256
|
+
options = {
|
|
257
|
+
...options,
|
|
258
|
+
transaction,
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
return [await this.find(options), await this.count(options)];
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Find By Id
|
|
266
|
+
*
|
|
267
|
+
*/
|
|
268
|
+
findById(id: string | number) {
|
|
269
|
+
return this.collection.model.findByPk(id);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Find one record from database
|
|
274
|
+
*
|
|
275
|
+
* @param options
|
|
276
|
+
*/
|
|
277
|
+
async findOne(options?: FindOneOptions) {
|
|
278
|
+
const transaction = await this.getTransaction(options);
|
|
279
|
+
|
|
280
|
+
const rows = await this.find({ ...options, limit: 1, transaction });
|
|
281
|
+
return rows.length == 1 ? rows[0] : null;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Save instance to database
|
|
286
|
+
*
|
|
287
|
+
* @param values
|
|
288
|
+
* @param options
|
|
289
|
+
*/
|
|
290
|
+
@transaction()
|
|
291
|
+
async create<M extends Model>(options: CreateOptions): Promise<M> {
|
|
292
|
+
const transaction = await this.getTransaction(options);
|
|
293
|
+
|
|
294
|
+
const guard = UpdateGuard.fromOptions(this.model, { ...options, action: 'create' });
|
|
295
|
+
const values = guard.sanitize(options.values || {});
|
|
296
|
+
|
|
297
|
+
const instance = await this.model.create<any>(values, {
|
|
298
|
+
...options,
|
|
299
|
+
transaction,
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
if (!instance) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
await updateAssociations(instance, values, {
|
|
307
|
+
...options,
|
|
308
|
+
transaction,
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
if (options.hooks !== false) {
|
|
312
|
+
await this.database.emitAsync(`${this.collection.name}.afterCreateWithAssociations`, instance, options);
|
|
313
|
+
await this.database.emitAsync(`${this.collection.name}.afterSaveWithAssociations`, instance, options);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return instance;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Save Many instances to database
|
|
321
|
+
*
|
|
322
|
+
* @param records
|
|
323
|
+
* @param options
|
|
324
|
+
*/
|
|
325
|
+
@transaction()
|
|
326
|
+
async createMany(options: CreateManyOptions) {
|
|
327
|
+
const transaction = await this.getTransaction(options);
|
|
328
|
+
const { records } = options;
|
|
329
|
+
const instances = [];
|
|
330
|
+
for (const values of records) {
|
|
331
|
+
const instance = await this.create({ values, transaction });
|
|
332
|
+
instances.push(instance);
|
|
333
|
+
}
|
|
334
|
+
return instances;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Update model value
|
|
339
|
+
*
|
|
340
|
+
* @param values
|
|
341
|
+
* @param options
|
|
342
|
+
*/
|
|
343
|
+
@transaction()
|
|
344
|
+
async update(options: UpdateOptions) {
|
|
345
|
+
const transaction = await this.getTransaction(options);
|
|
346
|
+
const guard = UpdateGuard.fromOptions(this.model, options);
|
|
347
|
+
|
|
348
|
+
const values = guard.sanitize(options.values);
|
|
349
|
+
|
|
350
|
+
const queryOptions = this.buildQueryOptions(options);
|
|
351
|
+
|
|
352
|
+
const instances = await this.find({
|
|
353
|
+
...queryOptions,
|
|
354
|
+
transaction,
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
for (const instance of instances) {
|
|
358
|
+
await updateModelByValues(instance, values, {
|
|
359
|
+
...options,
|
|
360
|
+
sanitized: true,
|
|
361
|
+
transaction,
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (options.hooks !== false) {
|
|
366
|
+
for (const instance of instances) {
|
|
367
|
+
await this.database.emitAsync(`${this.collection.name}.afterUpdateWithAssociations`, instance, options);
|
|
368
|
+
await this.database.emitAsync(`${this.collection.name}.afterSaveWithAssociations`, instance, options);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return instances;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
@transaction((args, transaction) => {
|
|
376
|
+
return {
|
|
377
|
+
filterByTk: args[0],
|
|
378
|
+
transaction,
|
|
379
|
+
};
|
|
380
|
+
})
|
|
381
|
+
async destroy(options?: TargetKey | TargetKey[] | DestroyOptions) {
|
|
382
|
+
const transaction = await this.getTransaction(options);
|
|
383
|
+
|
|
384
|
+
const modelFilterKey = this.collection.filterTargetKey;
|
|
385
|
+
|
|
386
|
+
options = <DestroyOptions>options;
|
|
387
|
+
|
|
388
|
+
if (options['individualHooks'] === undefined) {
|
|
389
|
+
options['individualHooks'] = true;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
const filterByTk: TargetKey[] | undefined =
|
|
393
|
+
options.filterByTk && !lodash.isArray(options.filterByTk)
|
|
394
|
+
? [options.filterByTk]
|
|
395
|
+
: (options.filterByTk as TargetKey[] | undefined);
|
|
396
|
+
|
|
397
|
+
if (filterByTk && !options.filter) {
|
|
398
|
+
return await this.model.destroy({
|
|
399
|
+
...options,
|
|
400
|
+
where: {
|
|
401
|
+
[modelFilterKey]: {
|
|
402
|
+
[Op.in]: filterByTk,
|
|
403
|
+
},
|
|
404
|
+
},
|
|
405
|
+
transaction,
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (options.filter) {
|
|
410
|
+
let pks = (
|
|
411
|
+
await this.find({
|
|
412
|
+
filter: options.filter,
|
|
413
|
+
transaction,
|
|
414
|
+
})
|
|
415
|
+
).map((instance) => instance.get(modelFilterKey) as TargetKey);
|
|
416
|
+
|
|
417
|
+
if (filterByTk) {
|
|
418
|
+
pks = lodash.intersection(
|
|
419
|
+
pks.map((i) => `${i}`),
|
|
420
|
+
filterByTk.map((i) => `${i}`),
|
|
421
|
+
);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
return await this.destroy({
|
|
425
|
+
...lodash.omit(options, 'filter'),
|
|
426
|
+
filterByTk: pks,
|
|
427
|
+
transaction,
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
if (options.truncate) {
|
|
432
|
+
return await this.model.destroy({
|
|
433
|
+
...options,
|
|
434
|
+
truncate: true,
|
|
435
|
+
transaction,
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* @param association target association
|
|
442
|
+
*/
|
|
443
|
+
relation<R extends RelationRepository>(association: string): RelationRepositoryBuilder<R> {
|
|
444
|
+
return new RelationRepositoryBuilder<R>(this.collection, association);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
protected buildQueryOptions(options: any) {
|
|
448
|
+
const parser = new OptionsParser(options, {
|
|
449
|
+
collection: this.collection,
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
const params = parser.toSequelizeParams();
|
|
453
|
+
debug('sequelize query params %o', params);
|
|
454
|
+
return { where: {}, ...options, ...params };
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
protected parseFilter(filter: Filter, options?: any) {
|
|
458
|
+
const parser = new FilterParser(filter, {
|
|
459
|
+
collection: this.collection,
|
|
460
|
+
app: {
|
|
461
|
+
ctx: options?.context,
|
|
462
|
+
},
|
|
463
|
+
});
|
|
464
|
+
return parser.toSequelizeParams();
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
protected async getTransaction(options: any, autoGen = false) {
|
|
468
|
+
if (lodash.isPlainObject(options) && options.transaction) {
|
|
469
|
+
return options.transaction;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
if (autoGen) {
|
|
473
|
+
return await this.model.sequelize.transaction();
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
return null;
|
|
477
|
+
}
|
|
478
|
+
}
|