json-fs-query 0.1.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/.browserslistrc +1 -0
- package/.nvmrc +1 -0
- package/LICENSE +674 -0
- package/MAIN.md +15 -0
- package/README.md +63 -0
- package/babel.config.js +3 -0
- package/build-tools.config.json +30 -0
- package/dist/data/introspect/create.d.ts +11 -0
- package/dist/data/introspect/create.js +45 -0
- package/dist/data/introspect/create.min.js +1 -0
- package/dist/data/introspect/definitions/field.d.ts +28 -0
- package/dist/data/introspect/definitions/field.js +36 -0
- package/dist/data/introspect/definitions/field.min.js +1 -0
- package/dist/data/introspect/definitions/key.d.ts +26 -0
- package/dist/data/introspect/definitions/key.js +53 -0
- package/dist/data/introspect/definitions/key.min.js +1 -0
- package/dist/data/introspect/definitions/keyReference.d.ts +18 -0
- package/dist/data/introspect/definitions/keyReference.js +20 -0
- package/dist/data/introspect/definitions/keyReference.min.js +1 -0
- package/dist/data/introspect/definitions/record.d.ts +26 -0
- package/dist/data/introspect/definitions/record.js +32 -0
- package/dist/data/introspect/definitions/record.min.js +1 -0
- package/dist/data/introspect/describe.d.ts +2 -0
- package/dist/data/introspect/describe.js +15 -0
- package/dist/data/introspect/describe.min.js +1 -0
- package/dist/data/introspect/drop.d.ts +2 -0
- package/dist/data/introspect/drop.js +37 -0
- package/dist/data/introspect/drop.min.js +1 -0
- package/dist/data/introspect/index.d.ts +8 -0
- package/dist/data/introspect/index.js +30 -0
- package/dist/data/introspect/index.min.js +1 -0
- package/dist/data/introspect/policies/foreignKeyExists.d.ts +9 -0
- package/dist/data/introspect/policies/foreignKeyExists.js +25 -0
- package/dist/data/introspect/policies/foreignKeyExists.min.js +1 -0
- package/dist/data/introspect/policies/keyGenerate.d.ts +2 -0
- package/dist/data/introspect/policies/keyGenerate.js +17 -0
- package/dist/data/introspect/policies/keyGenerate.min.js +1 -0
- package/dist/data/introspect/policies/keyUnique.d.ts +2 -0
- package/dist/data/introspect/policies/keyUnique.js +21 -0
- package/dist/data/introspect/policies/keyUnique.min.js +1 -0
- package/dist/data/introspect/policies/typeCheck.d.ts +12 -0
- package/dist/data/introspect/policies/typeCheck.js +57 -0
- package/dist/data/introspect/policies/typeCheck.min.js +1 -0
- package/dist/data/introspect/policies/typeEnum.d.ts +2 -0
- package/dist/data/introspect/policies/typeEnum.js +14 -0
- package/dist/data/introspect/policies/typeEnum.min.js +1 -0
- package/dist/data/introspect/policies/useDefault.d.ts +2 -0
- package/dist/data/introspect/policies/useDefault.js +13 -0
- package/dist/data/introspect/policies/useDefault.min.js +1 -0
- package/dist/data/queries/deleteEntity.d.ts +2 -0
- package/dist/data/queries/deleteEntity.js +79 -0
- package/dist/data/queries/deleteEntity.min.js +1 -0
- package/dist/data/queries/groupBy.d.ts +2 -0
- package/dist/data/queries/groupBy.js +22 -0
- package/dist/data/queries/groupBy.min.js +1 -0
- package/dist/data/queries/insertEntity.d.ts +2 -0
- package/dist/data/queries/insertEntity.js +115 -0
- package/dist/data/queries/insertEntity.min.js +1 -0
- package/dist/data/queries/joinEntity.d.ts +2 -0
- package/dist/data/queries/joinEntity.js +27 -0
- package/dist/data/queries/joinEntity.min.js +1 -0
- package/dist/data/queries/mergeJoins.d.ts +2 -0
- package/dist/data/queries/mergeJoins.js +19 -0
- package/dist/data/queries/mergeJoins.min.js +1 -0
- package/dist/data/queries/parser.d.ts +2 -0
- package/dist/data/queries/parser.js +30 -0
- package/dist/data/queries/parser.min.js +1 -0
- package/dist/data/queries/query.d.ts +2 -0
- package/dist/data/queries/query.js +18 -0
- package/dist/data/queries/query.min.js +1 -0
- package/dist/data/queries/readEntity.d.ts +2 -0
- package/dist/data/queries/readEntity.js +14 -0
- package/dist/data/queries/readEntity.min.js +1 -0
- package/dist/data/queries/sortBy.d.ts +2 -0
- package/dist/data/queries/sortBy.js +25 -0
- package/dist/data/queries/sortBy.min.js +1 -0
- package/dist/data/queries/updateEntity.d.ts +2 -0
- package/dist/data/queries/updateEntity.js +164 -0
- package/dist/data/queries/updateEntity.min.js +1 -0
- package/dist/data/queries/where.d.ts +7 -0
- package/dist/data/queries/where.js +56 -0
- package/dist/data/queries/where.min.js +1 -0
- package/dist/data/utilities/deregisterRecord.d.ts +8 -0
- package/dist/data/utilities/deregisterRecord.js +34 -0
- package/dist/data/utilities/deregisterRecord.min.js +1 -0
- package/dist/data/utilities/getConditionIndexedList.d.ts +3 -0
- package/dist/data/utilities/getConditionIndexedList.js +47 -0
- package/dist/data/utilities/getConditionIndexedList.min.js +1 -0
- package/dist/data/utilities/getJoinIndexedList.d.ts +3 -0
- package/dist/data/utilities/getJoinIndexedList.js +59 -0
- package/dist/data/utilities/getJoinIndexedList.min.js +1 -0
- package/dist/data/utilities/getMatchingIndexes.d.ts +2 -0
- package/dist/data/utilities/getMatchingIndexes.js +28 -0
- package/dist/data/utilities/getMatchingIndexes.min.js +1 -0
- package/dist/data/utilities/matchIndexedJoins.d.ts +2 -0
- package/dist/data/utilities/matchIndexedJoins.js +61 -0
- package/dist/data/utilities/matchIndexedJoins.min.js +1 -0
- package/dist/data/utilities/mergeJoin.d.ts +2 -0
- package/dist/data/utilities/mergeJoin.js +44 -0
- package/dist/data/utilities/mergeJoin.min.js +1 -0
- package/dist/data/utilities/parsers/findCommand.d.ts +10 -0
- package/dist/data/utilities/parsers/findCommand.js +25 -0
- package/dist/data/utilities/parsers/findCommand.min.js +1 -0
- package/dist/data/utilities/parsers/findConditions.d.ts +15 -0
- package/dist/data/utilities/parsers/findConditions.js +28 -0
- package/dist/data/utilities/parsers/findConditions.min.js +1 -0
- package/dist/data/utilities/parsers/findGroupBy.d.ts +9 -0
- package/dist/data/utilities/parsers/findGroupBy.js +22 -0
- package/dist/data/utilities/parsers/findGroupBy.min.js +1 -0
- package/dist/data/utilities/parsers/findInsertValues.d.ts +13 -0
- package/dist/data/utilities/parsers/findInsertValues.js +34 -0
- package/dist/data/utilities/parsers/findInsertValues.min.js +1 -0
- package/dist/data/utilities/parsers/findJoinClauses.d.ts +13 -0
- package/dist/data/utilities/parsers/findJoinClauses.js +27 -0
- package/dist/data/utilities/parsers/findJoinClauses.min.js +1 -0
- package/dist/data/utilities/parsers/findJoinEntity.d.ts +9 -0
- package/dist/data/utilities/parsers/findJoinEntity.js +22 -0
- package/dist/data/utilities/parsers/findJoinEntity.min.js +1 -0
- package/dist/data/utilities/parsers/findLimit.d.ts +9 -0
- package/dist/data/utilities/parsers/findLimit.js +22 -0
- package/dist/data/utilities/parsers/findLimit.min.js +1 -0
- package/dist/data/utilities/parsers/findMergeJoins.d.ts +12 -0
- package/dist/data/utilities/parsers/findMergeJoins.js +26 -0
- package/dist/data/utilities/parsers/findMergeJoins.min.js +1 -0
- package/dist/data/utilities/parsers/findOffset.d.ts +9 -0
- package/dist/data/utilities/parsers/findOffset.js +22 -0
- package/dist/data/utilities/parsers/findOffset.min.js +1 -0
- package/dist/data/utilities/parsers/findSelects.d.ts +12 -0
- package/dist/data/utilities/parsers/findSelects.js +30 -0
- package/dist/data/utilities/parsers/findSelects.min.js +1 -0
- package/dist/data/utilities/parsers/findSortClauses.d.ts +12 -0
- package/dist/data/utilities/parsers/findSortClauses.js +30 -0
- package/dist/data/utilities/parsers/findSortClauses.min.js +1 -0
- package/dist/data/utilities/parsers/findUpdateValues.d.ts +15 -0
- package/dist/data/utilities/parsers/findUpdateValues.js +34 -0
- package/dist/data/utilities/parsers/findUpdateValues.min.js +1 -0
- package/dist/data/utilities/parsers/isEntityProperty.d.ts +2 -0
- package/dist/data/utilities/parsers/isEntityProperty.js +8 -0
- package/dist/data/utilities/parsers/isEntityProperty.min.js +1 -0
- package/dist/data/utilities/parsers/parseLiteralValue.d.ts +12 -0
- package/dist/data/utilities/parsers/parseLiteralValue.js +34 -0
- package/dist/data/utilities/parsers/parseLiteralValue.min.js +1 -0
- package/dist/data/utilities/parsers/parseQuery.d.ts +33 -0
- package/dist/data/utilities/parsers/parseQuery.js +51 -0
- package/dist/data/utilities/parsers/parseQuery.min.js +1 -0
- package/dist/data/utilities/parsers/removeFromQuery.d.ts +2 -0
- package/dist/data/utilities/parsers/removeFromQuery.js +8 -0
- package/dist/data/utilities/parsers/removeFromQuery.min.js +1 -0
- package/dist/data/utilities/parsers/splitEntityProperty.d.ts +5 -0
- package/dist/data/utilities/parsers/splitEntityProperty.js +23 -0
- package/dist/data/utilities/parsers/splitEntityProperty.min.js +1 -0
- package/dist/data/utilities/parsers/splitQueries.d.ts +2 -0
- package/dist/data/utilities/parsers/splitQueries.js +11 -0
- package/dist/data/utilities/parsers/splitQueries.min.js +1 -0
- package/dist/data/utilities/reconcileJoin.d.ts +2 -0
- package/dist/data/utilities/reconcileJoin.js +26 -0
- package/dist/data/utilities/reconcileJoin.min.js +1 -0
- package/dist/data/utilities/reconcileJoins.d.ts +2 -0
- package/dist/data/utilities/reconcileJoins.js +27 -0
- package/dist/data/utilities/reconcileJoins.min.js +1 -0
- package/dist/data/utilities/registerRecord.d.ts +8 -0
- package/dist/data/utilities/registerRecord.js +67 -0
- package/dist/data/utilities/registerRecord.min.js +1 -0
- package/dist/data/utilities/removeFromIndex.d.ts +14 -0
- package/dist/data/utilities/removeFromIndex.js +46 -0
- package/dist/data/utilities/removeFromIndex.min.js +1 -0
- package/dist/data/utilities/restrictIndexedList.d.ts +2 -0
- package/dist/data/utilities/restrictIndexedList.js +45 -0
- package/dist/data/utilities/restrictIndexedList.min.js +1 -0
- package/dist/data/utilities/retrieveFile.d.ts +2 -0
- package/dist/data/utilities/retrieveFile.js +28 -0
- package/dist/data/utilities/retrieveFile.min.js +1 -0
- package/dist/data/utilities/retrieveIndexes.d.ts +2 -0
- package/dist/data/utilities/retrieveIndexes.js +24 -0
- package/dist/data/utilities/retrieveIndexes.min.js +1 -0
- package/dist/data/utilities/retrieveRecord.d.ts +2 -0
- package/dist/data/utilities/retrieveRecord.js +9 -0
- package/dist/data/utilities/retrieveRecord.min.js +1 -0
- package/dist/data/utilities/retrieveRecords.d.ts +2 -0
- package/dist/data/utilities/retrieveRecords.js +21 -0
- package/dist/data/utilities/retrieveRecords.min.js +1 -0
- package/dist/data/utilities/runQuery.d.ts +2 -0
- package/dist/data/utilities/runQuery.js +72 -0
- package/dist/data/utilities/runQuery.min.js +1 -0
- package/dist/data/utilities/updateIndex.d.ts +17 -0
- package/dist/data/utilities/updateIndex.js +56 -0
- package/dist/data/utilities/updateIndex.min.js +1 -0
- package/dist/data/utilities/useJoinClause.d.ts +6 -0
- package/dist/data/utilities/useJoinClause.js +51 -0
- package/dist/data/utilities/useJoinClause.min.js +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +35 -0
- package/dist/index.min.js +1 -0
- package/gulpfile.mjs +15 -0
- package/package.json +44 -0
- package/src/data/introspect/create.test.js +67 -0
- package/src/data/introspect/create.ts +29 -0
- package/src/data/introspect/definitions/field.test.js +23 -0
- package/src/data/introspect/definitions/field.ts +48 -0
- package/src/data/introspect/definitions/key.test.js +100 -0
- package/src/data/introspect/definitions/key.ts +64 -0
- package/src/data/introspect/definitions/keyReference.test.js +8 -0
- package/src/data/introspect/definitions/keyReference.ts +23 -0
- package/src/data/introspect/definitions/record.ts +42 -0
- package/src/data/introspect/describe.test.js +36 -0
- package/src/data/introspect/describe.ts +9 -0
- package/src/data/introspect/drop.test.js +77 -0
- package/src/data/introspect/drop.ts +20 -0
- package/src/data/introspect/index.ts +8 -0
- package/src/data/introspect/policies/foreignKeyExists.test.js +44 -0
- package/src/data/introspect/policies/foreignKeyExists.ts +15 -0
- package/src/data/introspect/policies/keyGenerate.ts +11 -0
- package/src/data/introspect/policies/keyUnique.ts +11 -0
- package/src/data/introspect/policies/typeCheck.test.js +84 -0
- package/src/data/introspect/policies/typeCheck.ts +49 -0
- package/src/data/introspect/policies/typeEnum.ts +6 -0
- package/src/data/introspect/policies/useDefault.ts +6 -0
- package/src/data/queries/deleteEntity.test.js +86 -0
- package/src/data/queries/deleteEntity.ts +56 -0
- package/src/data/queries/groupBy.test.js +135 -0
- package/src/data/queries/groupBy.ts +16 -0
- package/src/data/queries/insertEntity.test.js +156 -0
- package/src/data/queries/insertEntity.ts +113 -0
- package/src/data/queries/joinEntity.test.js +109 -0
- package/src/data/queries/joinEntity.ts +20 -0
- package/src/data/queries/mergeJoins.test.js +174 -0
- package/src/data/queries/mergeJoins.ts +13 -0
- package/src/data/queries/parser.test.js +343 -0
- package/src/data/queries/parser.ts +24 -0
- package/src/data/queries/query.test.js +233 -0
- package/src/data/queries/query.ts +12 -0
- package/src/data/queries/readEntity.test.js +85 -0
- package/src/data/queries/readEntity.ts +8 -0
- package/src/data/queries/sortBy.test.js +131 -0
- package/src/data/queries/sortBy.ts +18 -0
- package/src/data/queries/updateEntity.test.js +228 -0
- package/src/data/queries/updateEntity.ts +162 -0
- package/src/data/queries/where.test.js +129 -0
- package/src/data/queries/where.ts +54 -0
- package/src/data/utilities/deregisterRecord.test.js +26 -0
- package/src/data/utilities/deregisterRecord.ts +24 -0
- package/src/data/utilities/getConditionIndexedList.ts +43 -0
- package/src/data/utilities/getJoinIndexedList.ts +53 -0
- package/src/data/utilities/getMatchingIndexes.ts +21 -0
- package/src/data/utilities/matchIndexedJoins.ts +45 -0
- package/src/data/utilities/mergeJoin.test.js +102 -0
- package/src/data/utilities/mergeJoin.ts +28 -0
- package/src/data/utilities/parsers/findCommand.ts +25 -0
- package/src/data/utilities/parsers/findConditions.test.js +38 -0
- package/src/data/utilities/parsers/findConditions.ts +32 -0
- package/src/data/utilities/parsers/findGroupBy.ts +20 -0
- package/src/data/utilities/parsers/findInsertValues.test.js +26 -0
- package/src/data/utilities/parsers/findInsertValues.ts +32 -0
- package/src/data/utilities/parsers/findJoinClauses.ts +29 -0
- package/src/data/utilities/parsers/findJoinEntity.ts +20 -0
- package/src/data/utilities/parsers/findLimit.ts +20 -0
- package/src/data/utilities/parsers/findMergeJoins.ts +27 -0
- package/src/data/utilities/parsers/findOffset.ts +20 -0
- package/src/data/utilities/parsers/findSelects.ts +31 -0
- package/src/data/utilities/parsers/findSortClauses.ts +31 -0
- package/src/data/utilities/parsers/findUpdateValues.test.js +37 -0
- package/src/data/utilities/parsers/findUpdateValues.ts +32 -0
- package/src/data/utilities/parsers/isEntityProperty.ts +1 -0
- package/src/data/utilities/parsers/parseLiteralValue.test.js +41 -0
- package/src/data/utilities/parsers/parseLiteralValue.ts +29 -0
- package/src/data/utilities/parsers/parseQuery.ts +73 -0
- package/src/data/utilities/parsers/removeFromQuery.ts +1 -0
- package/src/data/utilities/parsers/splitEntityProperty.test.js +8 -0
- package/src/data/utilities/parsers/splitEntityProperty.ts +17 -0
- package/src/data/utilities/parsers/splitQueries.test.js +33 -0
- package/src/data/utilities/parsers/splitQueries.ts +4 -0
- package/src/data/utilities/reconcileJoin.test.js +38 -0
- package/src/data/utilities/reconcileJoin.ts +23 -0
- package/src/data/utilities/reconcileJoins.test.js +160 -0
- package/src/data/utilities/reconcileJoins.ts +15 -0
- package/src/data/utilities/registerRecord.test.js +44 -0
- package/src/data/utilities/registerRecord.ts +44 -0
- package/src/data/utilities/removeFromIndex.test.js +44 -0
- package/src/data/utilities/removeFromIndex.ts +34 -0
- package/src/data/utilities/restrictIndexedList.ts +38 -0
- package/src/data/utilities/retrieveFile.test.js +49 -0
- package/src/data/utilities/retrieveFile.ts +19 -0
- package/src/data/utilities/retrieveIndexes.ts +17 -0
- package/src/data/utilities/retrieveRecord.ts +3 -0
- package/src/data/utilities/retrieveRecords.test.js +223 -0
- package/src/data/utilities/retrieveRecords.ts +16 -0
- package/src/data/utilities/runQuery.test.js +88 -0
- package/src/data/utilities/runQuery.ts +75 -0
- package/src/data/utilities/updateIndex.test.js +44 -0
- package/src/data/utilities/updateIndex.ts +45 -0
- package/src/data/utilities/useJoinClause.test.js +94 -0
- package/src/data/utilities/useJoinClause.ts +44 -0
- package/src/global.d.ts +1 -0
- package/src/index.test.js +52 -0
- package/src/index.ts +17 -0
- package/test-data/__RECORDS.json +32 -0
- package/test-data/__indexes/exercise_muscle/fk_exercise_id.json +14 -0
- package/test-data/__indexes/exercise_muscle/fk_muscle_id.json +14 -0
- package/test-data/__indexes/exercise_muscle/pk__id.json +14 -0
- package/test-data/__indexes/exercises/pk__id.json +14 -0
- package/test-data/__indexes/muscles/pk__id.json +58 -0
- package/test-data/__indexes/workouts/fk_exercise_id.json +23 -0
- package/test-data/__indexes/workouts/index_date.json +18 -0
- package/test-data/__indexes/workouts/pk__id.json +26 -0
- package/test-data/copyDatabase.ts +64 -0
- package/test-data/exercise_muscle/bench_press_pectorals.json +6 -0
- package/test-data/exercise_muscle/deadlift_hamstrings.json +6 -0
- package/test-data/exercise_muscle/squat_quadriceps.json +6 -0
- package/test-data/exercise_muscle.json +69 -0
- package/test-data/exercises/bench_press.json +5 -0
- package/test-data/exercises/deadlift.json +5 -0
- package/test-data/exercises/squat.json +5 -0
- package/test-data/exercises.json +34 -0
- package/test-data/muscles/abdominal.json +6 -0
- package/test-data/muscles/biceps.json +6 -0
- package/test-data/muscles/calves.json +6 -0
- package/test-data/muscles/deltoids.json +6 -0
- package/test-data/muscles/erector_spinae.json +6 -0
- package/test-data/muscles/forearms.json +6 -0
- package/test-data/muscles/gluteus_maximus.json +6 -0
- package/test-data/muscles/hamstrings.json +6 -0
- package/test-data/muscles/latissimus_dorsi.json +6 -0
- package/test-data/muscles/obliques.json +6 -0
- package/test-data/muscles/pectorals.json +6 -0
- package/test-data/muscles/quadriceps.json +6 -0
- package/test-data/muscles/trapezius.json +6 -0
- package/test-data/muscles/triceps.json +6 -0
- package/test-data/muscles.json +50 -0
- package/test-data/workouts/2024-06-02-001.json +10 -0
- package/test-data/workouts/2024-06-02-002.json +10 -0
- package/test-data/workouts/2024-06-02-003.json +10 -0
- package/test-data/workouts/2024-06-05-001.json +10 -0
- package/test-data/workouts/2024-06-05-002.json +10 -0
- package/test-data/workouts/2024-06-05-003.json +10 -0
- package/test-data/workouts.json +84 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true
|
|
5
|
+
})
|
|
6
|
+
exports.updateEntity = void 0
|
|
7
|
+
require('core-js/modules/es.json.stringify.js')
|
|
8
|
+
require('core-js/modules/esnext.iterator.constructor.js')
|
|
9
|
+
require('core-js/modules/esnext.iterator.find.js')
|
|
10
|
+
const _retrieveRecord = require('../utilities/retrieveRecord')
|
|
11
|
+
const _retrieveFile = require('../utilities/retrieveFile')
|
|
12
|
+
const _updateIndex = require('../utilities/updateIndex')
|
|
13
|
+
const _removeFromIndex = require('../utilities/removeFromIndex')
|
|
14
|
+
const _keyUnique = require('../introspect/policies/keyUnique')
|
|
15
|
+
const _typeCheck = require('../introspect/policies/typeCheck')
|
|
16
|
+
const _foreignKeyExists = require('../introspect/policies/foreignKeyExists')
|
|
17
|
+
const _splitEntityProperty = require('../utilities/parsers/splitEntityProperty')
|
|
18
|
+
const gulpConfig = require('js-build-tools/gulp.config')
|
|
19
|
+
const {
|
|
20
|
+
writeFile
|
|
21
|
+
} = require('fs/promises')
|
|
22
|
+
/**
|
|
23
|
+
* Same reasoning as deleteEntity: a record object carries no memory of which entry file it came
|
|
24
|
+
* from, so re-scan entries[] and match by the record's own primary key value.
|
|
25
|
+
* @param record
|
|
26
|
+
* @param primaryField
|
|
27
|
+
* @param primaryValue
|
|
28
|
+
*/
|
|
29
|
+
const findEntryFile = async (record, primaryField, primaryValue) => {
|
|
30
|
+
for (const fileName of record.entries) {
|
|
31
|
+
const data = await (0, _retrieveFile.retrieveFile)(`${record.path}/${fileName}`)
|
|
32
|
+
if (data[primaryField] == primaryValue) {
|
|
33
|
+
return fileName
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return null
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Only check uniqueness for a single-field primary/unique key whose value is actually changing -
|
|
40
|
+
* checking an unchanged value would find the record's own existing entry and wrongly report it
|
|
41
|
+
* as a duplicate of itself.
|
|
42
|
+
* @param entity
|
|
43
|
+
* @param record
|
|
44
|
+
* @param oldData
|
|
45
|
+
* @param newValues
|
|
46
|
+
*/
|
|
47
|
+
const assertUniqueForUpdate = async (entity, record, oldData, newValues) => {
|
|
48
|
+
for (const key of record.keys) {
|
|
49
|
+
if (key.type !== 'primary' && key.type !== 'unique' || key.fields.length !== 1) {
|
|
50
|
+
continue
|
|
51
|
+
}
|
|
52
|
+
const field = key.fields[0]
|
|
53
|
+
if (!newValues.hasOwnProperty(field) || newValues[field] == oldData[field]) {
|
|
54
|
+
continue
|
|
55
|
+
}
|
|
56
|
+
const isUnique = await (0, _keyUnique.keyUnique)(entity, key.fields, newValues[field])
|
|
57
|
+
if (!isUnique) {
|
|
58
|
+
throw new Error(`Duplicate value for ${key.type} key "${field}" on ${entity}`)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Move a single-field key's index entry from the old value to the new one wherever the update
|
|
64
|
+
* actually changed that field.
|
|
65
|
+
* @param record
|
|
66
|
+
* @param oldData
|
|
67
|
+
* @param newData
|
|
68
|
+
* @param newValues
|
|
69
|
+
* @param fileName
|
|
70
|
+
*/
|
|
71
|
+
/**
|
|
72
|
+
* Same "only if it actually changed" scoping as assertUniqueForUpdate: re-checking an unchanged
|
|
73
|
+
* foreign key value would re-validate a reference this update never touches, which could fail an
|
|
74
|
+
* unrelated field's update if that parent record happened to be deleted since.
|
|
75
|
+
* @param entity
|
|
76
|
+
* @param record
|
|
77
|
+
* @param oldData
|
|
78
|
+
* @param newValues
|
|
79
|
+
*/
|
|
80
|
+
const assertForeignKeysForUpdate = async (entity, record, oldData, newValues) => {
|
|
81
|
+
for (const key of record.keys) {
|
|
82
|
+
if (key.type !== 'foreign' || key.fields.length !== 1 || !key.references || key.references.length !== 1) {
|
|
83
|
+
continue
|
|
84
|
+
}
|
|
85
|
+
const field = key.fields[0]
|
|
86
|
+
if (!newValues.hasOwnProperty(field) || newValues[field] == oldData[field]) {
|
|
87
|
+
continue
|
|
88
|
+
}
|
|
89
|
+
const {
|
|
90
|
+
entity: refEntity,
|
|
91
|
+
property: refProperty
|
|
92
|
+
} = (0, _splitEntityProperty.splitEntityProperty)(key.references[0].fields[0])
|
|
93
|
+
const exists = await (0, _foreignKeyExists.foreignKeyExists)(refEntity, refProperty, newValues[field])
|
|
94
|
+
if (!exists) {
|
|
95
|
+
throw new Error(`Foreign key "${field}" on ${entity} references a nonexistent ${refEntity}.${refProperty} = ${newValues[field]}`)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const reconcileIndexes = async (record, oldData, newData, newValues, fileName) => {
|
|
100
|
+
for (const key of record.keys) {
|
|
101
|
+
if (key.fields.length !== 1) {
|
|
102
|
+
continue
|
|
103
|
+
}
|
|
104
|
+
const field = key.fields[0]
|
|
105
|
+
if (!newValues.hasOwnProperty(field) || newValues[field] == oldData[field]) {
|
|
106
|
+
continue
|
|
107
|
+
}
|
|
108
|
+
await (0, _removeFromIndex.removeFromIndex)(record.path, key, oldData[field], fileName)
|
|
109
|
+
await (0, _updateIndex.updateIndex)(record.path, key, newData[field], fileName)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const assertRequiredFields = (entity, record, newData) => {
|
|
113
|
+
for (const field of record.definition) {
|
|
114
|
+
if (!field.optional && typeof newData[field.name] === 'undefined') {
|
|
115
|
+
throw new Error(`Missing required field "${field.name}" for ${entity}`)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Type-check (and coerce) only the fields actually present in an update's values, never the rest
|
|
121
|
+
* of the merged record - a field whose already-stored value doesn't match its declared type
|
|
122
|
+
* (nothing enforced this before typeCheck() existed) must not block an update that never touches
|
|
123
|
+
* that field.
|
|
124
|
+
* @param record
|
|
125
|
+
* @param values
|
|
126
|
+
*/
|
|
127
|
+
const applyFieldTypes = (record, values) => {
|
|
128
|
+
const typedValues = Object.assign({}, values)
|
|
129
|
+
for (const field of record.definition) {
|
|
130
|
+
if (typedValues.hasOwnProperty(field.name)) {
|
|
131
|
+
typedValues[field.name] = (0, _typeCheck.typeCheck)(field.type, typedValues[field.name])
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return typedValues
|
|
135
|
+
}
|
|
136
|
+
const updateEntity = async (entity = '', values = {}, dataSet = {}) => {
|
|
137
|
+
const databasePath = gulpConfig.get('databasePath', 'database/')
|
|
138
|
+
const record = await (0, _retrieveRecord.retrieveRecord)(entity)
|
|
139
|
+
const primaryKey = record.keys.find(key => key.type === 'primary' && key.fields.length === 1)
|
|
140
|
+
if (!primaryKey) {
|
|
141
|
+
throw new Error(`Cannot update "${entity}" without a single-field primary key`)
|
|
142
|
+
}
|
|
143
|
+
const primaryField = primaryKey.fields[0]
|
|
144
|
+
const typedValues = applyFieldTypes(record, values)
|
|
145
|
+
const toUpdate = dataSet[entity] || []
|
|
146
|
+
const updatedRows = []
|
|
147
|
+
for (const row of toUpdate) {
|
|
148
|
+
const fileName = await findEntryFile(record, primaryField, row[primaryField])
|
|
149
|
+
if (!fileName) {
|
|
150
|
+
throw new Error(`Could not find entry for ${entity} where "${primaryField}" = ${row[primaryField]}`)
|
|
151
|
+
}
|
|
152
|
+
const oldData = await (0, _retrieveFile.retrieveFile)(`${record.path}/${fileName}`)
|
|
153
|
+
await assertUniqueForUpdate(entity, record, oldData, typedValues)
|
|
154
|
+
await assertForeignKeysForUpdate(entity, record, oldData, typedValues)
|
|
155
|
+
const newData = Object.assign({}, oldData, typedValues)
|
|
156
|
+
assertRequiredFields(entity, record, newData)
|
|
157
|
+
await reconcileIndexes(record, oldData, newData, typedValues, fileName)
|
|
158
|
+
await writeFile(`${databasePath}${record.path}/${fileName}`, JSON.stringify(newData, null, 2))
|
|
159
|
+
updatedRows.push(newData)
|
|
160
|
+
}
|
|
161
|
+
dataSet[entity] = updatedRows
|
|
162
|
+
return dataSet
|
|
163
|
+
}
|
|
164
|
+
exports.updateEntity = updateEntity
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.updateEntity=void 0,require("core-js/modules/es.json.stringify.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js");var _retrieveRecord=require("../utilities/retrieveRecord"),_retrieveFile=require("../utilities/retrieveFile"),_updateIndex=require("../utilities/updateIndex"),_removeFromIndex=require("../utilities/removeFromIndex"),_keyUnique=require("../introspect/policies/keyUnique"),_typeCheck=require("../introspect/policies/typeCheck"),_foreignKeyExists=require("../introspect/policies/foreignKeyExists"),_splitEntityProperty=require("../utilities/parsers/splitEntityProperty");const gulpConfig=require("js-build-tools/gulp.config"),{writeFile:writeFile}=require("fs/promises"),findEntryFile=async(e,t,r)=>{for(const i of e.entries){if((await(0,_retrieveFile.retrieveFile)(`${e.path}/${i}`))[t]==r)return i}return null},assertUniqueForUpdate=async(e,t,r,i)=>{for(const n of t.keys){if("primary"!==n.type&&"unique"!==n.type||1!==n.fields.length)continue;const t=n.fields[0];if(!i.hasOwnProperty(t)||i[t]==r[t])continue;if(!await(0,_keyUnique.keyUnique)(e,n.fields,i[t]))throw new Error(`Duplicate value for ${n.type} key "${t}" on ${e}`)}},assertForeignKeysForUpdate=async(e,t,r,i)=>{for(const n of t.keys){if("foreign"!==n.type||1!==n.fields.length||!n.references||1!==n.references.length)continue;const t=n.fields[0];if(!i.hasOwnProperty(t)||i[t]==r[t])continue;const{entity:s,property:o}=(0,_splitEntityProperty.splitEntityProperty)(n.references[0].fields[0]);if(!await(0,_foreignKeyExists.foreignKeyExists)(s,o,i[t]))throw new Error(`Foreign key "${t}" on ${e} references a nonexistent ${s}.${o} = ${i[t]}`)}},reconcileIndexes=async(e,t,r,i,n)=>{for(const s of e.keys){if(1!==s.fields.length)continue;const o=s.fields[0];i.hasOwnProperty(o)&&i[o]!=t[o]&&(await(0,_removeFromIndex.removeFromIndex)(e.path,s,t[o],n),await(0,_updateIndex.updateIndex)(e.path,s,r[o],n))}},assertRequiredFields=(e,t,r)=>{for(const i of t.definition)if(!i.optional&&void 0===r[i.name])throw new Error(`Missing required field "${i.name}" for ${e}`)},applyFieldTypes=(e,t)=>{const r=Object.assign({},t);for(const t of e.definition)r.hasOwnProperty(t.name)&&(r[t.name]=(0,_typeCheck.typeCheck)(t.type,r[t.name]));return r},updateEntity=async(e="",t={},r={})=>{const i=gulpConfig.get("databasePath","database/"),n=await(0,_retrieveRecord.retrieveRecord)(e),s=n.keys.find((e=>"primary"===e.type&&1===e.fields.length));if(!s)throw new Error(`Cannot update "${e}" without a single-field primary key`);const o=s.fields[0],a=applyFieldTypes(n,t),p=r[e]||[],l=[];for(const t of p){const r=await findEntryFile(n,o,t[o]);if(!r)throw new Error(`Could not find entry for ${e} where "${o}" = ${t[o]}`);const s=await(0,_retrieveFile.retrieveFile)(`${n.path}/${r}`);await assertUniqueForUpdate(e,n,s,a),await assertForeignKeysForUpdate(e,n,s,a);const p=Object.assign({},s,a);assertRequiredFields(e,n,p),await reconcileIndexes(n,s,p,a,r),await writeFile(`${i}${n.path}/${r}`,JSON.stringify(p,null,2)),l.push(p)}return r[e]=l,r};exports.updateEntity=updateEntity;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true
|
|
5
|
+
})
|
|
6
|
+
exports.where = void 0
|
|
7
|
+
require('core-js/modules/es.array.includes.js')
|
|
8
|
+
require('core-js/modules/esnext.iterator.constructor.js')
|
|
9
|
+
require('core-js/modules/esnext.iterator.filter.js')
|
|
10
|
+
const likeMatch = (dataValue, pattern) => {
|
|
11
|
+
if (typeof dataValue !== 'string' || typeof pattern !== 'string') {
|
|
12
|
+
return false
|
|
13
|
+
}
|
|
14
|
+
const regexPattern = pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/%/g, '.*').replace(/_/g, '.')
|
|
15
|
+
return new RegExp(`^${regexPattern}$`, 'i').test(dataValue)
|
|
16
|
+
}
|
|
17
|
+
const makeCondition = (data, property, comparator, value) => {
|
|
18
|
+
if (!data.hasOwnProperty(property)) {
|
|
19
|
+
return false
|
|
20
|
+
}
|
|
21
|
+
const dataValue = data[property]
|
|
22
|
+
switch (comparator) {
|
|
23
|
+
case '=':
|
|
24
|
+
return dataValue == value
|
|
25
|
+
case '!=':
|
|
26
|
+
case '<>':
|
|
27
|
+
return dataValue != value
|
|
28
|
+
case '>':
|
|
29
|
+
return dataValue > value
|
|
30
|
+
case '>=':
|
|
31
|
+
return dataValue >= value
|
|
32
|
+
case '<':
|
|
33
|
+
return dataValue < value
|
|
34
|
+
case '<=':
|
|
35
|
+
return dataValue <= value
|
|
36
|
+
case 'in':
|
|
37
|
+
return Array.isArray(value) && value.includes(dataValue)
|
|
38
|
+
case 'between':
|
|
39
|
+
return Array.isArray(value) && value.length === 2 && dataValue >= value[0] && dataValue <= value[1]
|
|
40
|
+
case 'like':
|
|
41
|
+
return likeMatch(dataValue, value)
|
|
42
|
+
}
|
|
43
|
+
return false
|
|
44
|
+
}
|
|
45
|
+
const where = (dataSet = [], {
|
|
46
|
+
property = '',
|
|
47
|
+
joinEntity = undefined,
|
|
48
|
+
comparator = '=',
|
|
49
|
+
value = null
|
|
50
|
+
} = {}) => {
|
|
51
|
+
return dataSet.filter(data => {
|
|
52
|
+
const testProperty = joinEntity ? `${joinEntity}.${property}` : property
|
|
53
|
+
return makeCondition(data, testProperty, comparator, value)
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
exports.where = where
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.where=void 0,require("core-js/modules/es.array.includes.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.filter.js");const likeMatch=(e,r)=>{if("string"!=typeof e||"string"!=typeof r)return!1;const t=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/%/g,".*").replace(/_/g,".");return new RegExp(`^${t}$`,"i").test(e)},makeCondition=(e,r,t,s)=>{if(!e.hasOwnProperty(r))return!1;const n=e[r];switch(t){case"=":return n==s;case"!=":case"<>":return n!=s;case">":return n>s;case">=":return n>=s;case"<":return n<s;case"<=":return n<=s;case"in":return Array.isArray(s)&&s.includes(n);case"between":return Array.isArray(s)&&2===s.length&&n>=s[0]&&n<=s[1];case"like":return likeMatch(n,s)}return!1},where=(e=[],{property:r="",joinEntity:t,comparator:s="=",value:n=null}={})=>e.filter((e=>makeCondition(e,t?`${t}.${r}`:r,s,n)));exports.where=where;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { recordDefinition } from '../introspect/definitions/record';
|
|
2
|
+
/**
|
|
3
|
+
* Remove a record's filename from the __RECORDS registry. A missing registry file is left
|
|
4
|
+
* untouched rather than created, since there's nothing to remove from it.
|
|
5
|
+
* @param recordName
|
|
6
|
+
*/
|
|
7
|
+
export declare const deregisterRecord: (recordName: string) => Promise<recordDefinition | null>;
|
|
8
|
+
//# sourceMappingURL=deregisterRecord.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true
|
|
5
|
+
})
|
|
6
|
+
exports.deregisterRecord = void 0
|
|
7
|
+
require('core-js/modules/es.json.stringify.js')
|
|
8
|
+
require('core-js/modules/esnext.iterator.constructor.js')
|
|
9
|
+
require('core-js/modules/esnext.iterator.filter.js')
|
|
10
|
+
const gulpConfig = require('js-build-tools/gulp.config')
|
|
11
|
+
const {
|
|
12
|
+
readFile,
|
|
13
|
+
writeFile
|
|
14
|
+
} = require('fs/promises')
|
|
15
|
+
/**
|
|
16
|
+
* Remove a record's filename from the __RECORDS registry. A missing registry file is left
|
|
17
|
+
* untouched rather than created, since there's nothing to remove from it.
|
|
18
|
+
* @param recordName
|
|
19
|
+
*/
|
|
20
|
+
const deregisterRecord = async recordName => {
|
|
21
|
+
const databasePath = gulpConfig.get('databasePath', 'database/')
|
|
22
|
+
const registryPath = `${databasePath}__RECORDS.json`
|
|
23
|
+
let registry
|
|
24
|
+
try {
|
|
25
|
+
registry = JSON.parse(await readFile(registryPath, 'utf8'))
|
|
26
|
+
} catch (err) {
|
|
27
|
+
return null
|
|
28
|
+
}
|
|
29
|
+
const fileName = `${recordName}.json`
|
|
30
|
+
registry.entries = registry.entries.filter(entry => entry !== fileName)
|
|
31
|
+
await writeFile(registryPath, JSON.stringify(registry, null, 2))
|
|
32
|
+
return registry
|
|
33
|
+
}
|
|
34
|
+
exports.deregisterRecord = deregisterRecord
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.deregisterRecord=void 0,require("core-js/modules/es.json.stringify.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.filter.js");const gulpConfig=require("js-build-tools/gulp.config"),{readFile:readFile,writeFile:writeFile}=require("fs/promises"),deregisterRecord=async e=>{const r=`${gulpConfig.get("databasePath","database/")}__RECORDS.json`;let t;try{t=JSON.parse(await readFile(r,"utf8"))}catch(e){return null}const s=`${e}.json`;return t.entries=t.entries.filter((e=>e!==s)),await writeFile(r,JSON.stringify(t,null,2)),t};exports.deregisterRecord=deregisterRecord;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true
|
|
5
|
+
})
|
|
6
|
+
exports.getConditionIndexedList = void 0
|
|
7
|
+
const _isEntityProperty = require('./parsers/isEntityProperty')
|
|
8
|
+
const _splitEntityProperty = require('./parsers/splitEntityProperty')
|
|
9
|
+
const _retrieveRecord = require('./retrieveRecord')
|
|
10
|
+
const _where = require('../queries/where')
|
|
11
|
+
const _retrieveFile = require('./retrieveFile')
|
|
12
|
+
const _getMatchingIndexes = require('./getMatchingIndexes')
|
|
13
|
+
const getConditionIndexedList = async (parsed, recordData, dataSet) => {
|
|
14
|
+
const reducedConditions = []
|
|
15
|
+
for (const condition of parsed.conditions) {
|
|
16
|
+
let entity = parsed.entity
|
|
17
|
+
let property = condition.property
|
|
18
|
+
if ((0, _isEntityProperty.isEntityProperty)(property)) {
|
|
19
|
+
const entityProperty = (0, _splitEntityProperty.splitEntityProperty)(property)
|
|
20
|
+
entity = entityProperty.entity
|
|
21
|
+
property = entityProperty.property
|
|
22
|
+
}
|
|
23
|
+
if (!recordData.hasOwnProperty(entity)) {
|
|
24
|
+
recordData[entity] = await (0, _retrieveRecord.retrieveRecord)(entity)
|
|
25
|
+
}
|
|
26
|
+
const indexed = {}
|
|
27
|
+
const retrieveMatchedFiles = async (entity, property, recordData, condition, dataSet, indexed) => {
|
|
28
|
+
const matchedRecords = (0, _where.where)(indexed[entity][property], {
|
|
29
|
+
property: 'value',
|
|
30
|
+
comparator: condition.comparator,
|
|
31
|
+
value: condition.value
|
|
32
|
+
})
|
|
33
|
+
for (const matchedRecord of matchedRecords) {
|
|
34
|
+
for (const file of matchedRecord.record) {
|
|
35
|
+
dataSet[entity].push(await (0, _retrieveFile.retrieveFile)(`${entity}/${file}`))
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const isIndexed = await (0, _getMatchingIndexes.getMatchingIndexes)(entity, property, recordData, condition, dataSet, indexed, retrieveMatchedFiles)
|
|
40
|
+
if (!isIndexed) {
|
|
41
|
+
reducedConditions.push(condition)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
parsed.conditions = reducedConditions
|
|
45
|
+
return parsed
|
|
46
|
+
}
|
|
47
|
+
exports.getConditionIndexedList = getConditionIndexedList
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.getConditionIndexedList=void 0;var _isEntityProperty=require("./parsers/isEntityProperty"),_splitEntityProperty=require("./parsers/splitEntityProperty"),_retrieveRecord=require("./retrieveRecord"),_where=require("../queries/where"),_retrieveFile=require("./retrieveFile"),_getMatchingIndexes=require("./getMatchingIndexes");const getConditionIndexedList=async(e,t,r)=>{let i=[];for(let o of e.conditions){let n=e.entity,s=o.property;if((0,_isEntityProperty.isEntityProperty)(s)){const e=(0,_splitEntityProperty.splitEntityProperty)(s);n=e.entity,s=e.property}t.hasOwnProperty(n)||(t[n]=await(0,_retrieveRecord.retrieveRecord)(n));const p={},d=async(e,t,r,i,o,n)=>{const s=(0,_where.where)(n[e][t],{property:"value",comparator:i.comparator,value:i.value});for(let t of s)for(let r of t.record)o[e].push(await(0,_retrieveFile.retrieveFile)(`${e}/${r}`))};await(0,_getMatchingIndexes.getMatchingIndexes)(n,s,t,o,r,p,d)||i.push(o)}return e.conditions=i,e};exports.getConditionIndexedList=getConditionIndexedList;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true
|
|
5
|
+
})
|
|
6
|
+
exports.getJoinIndexedList = void 0
|
|
7
|
+
const _siFunciona = _interopRequireDefault(require('si-funciona'))
|
|
8
|
+
const _splitEntityProperty = require('./parsers/splitEntityProperty')
|
|
9
|
+
const _retrieveRecord = require('./retrieveRecord')
|
|
10
|
+
const _getMatchingIndexes = require('./getMatchingIndexes')
|
|
11
|
+
const _matchIndexedJoins = require('./matchIndexedJoins')
|
|
12
|
+
const _restrictIndexedList = require('./restrictIndexedList')
|
|
13
|
+
function _interopRequireDefault (e) { return e && e.__esModule ? e : { default: e } }
|
|
14
|
+
const getJoinIndexedList = async (parsed, recordData, dataSets) => {
|
|
15
|
+
const reducedJoins = []
|
|
16
|
+
const indexed = {}
|
|
17
|
+
let firstIteration = true
|
|
18
|
+
const entity = parsed.entity
|
|
19
|
+
const joinEntity = parsed.joinEntity
|
|
20
|
+
const joinClauses = parsed.joinClauses
|
|
21
|
+
for (const anEntity in dataSets[entity]) {
|
|
22
|
+
const currentEntity = dataSets[entity][anEntity]
|
|
23
|
+
// Loop over each of the main entities
|
|
24
|
+
const filterJoins = {}
|
|
25
|
+
filterJoins[entity] = [_siFunciona.default.cloneObject(currentEntity)]
|
|
26
|
+
for (const joinClause of joinClauses) {
|
|
27
|
+
let indexedClone = _siFunciona.default.cloneObject(indexed)
|
|
28
|
+
const {
|
|
29
|
+
entity: entityA,
|
|
30
|
+
property: propertyA
|
|
31
|
+
} = (0, _splitEntityProperty.splitEntityProperty)(joinClause.propertyA)
|
|
32
|
+
const {
|
|
33
|
+
entity: entityB,
|
|
34
|
+
property: propertyB
|
|
35
|
+
} = (0, _splitEntityProperty.splitEntityProperty)(joinClause.propertyB)
|
|
36
|
+
// Get the record for the entities A and B, store on the recordData
|
|
37
|
+
if (!recordData.hasOwnProperty(entityA)) {
|
|
38
|
+
recordData[entityA] = await (0, _retrieveRecord.retrieveRecord)(entityA)
|
|
39
|
+
}
|
|
40
|
+
if (!recordData.hasOwnProperty(entityB)) {
|
|
41
|
+
recordData[entityB] = await (0, _retrieveRecord.retrieveRecord)(entityB)
|
|
42
|
+
}
|
|
43
|
+
indexedClone = (0, _restrictIndexedList.restrictIndexedList)(joinClause, filterJoins, indexedClone)
|
|
44
|
+
const retrieveMatchedFiles = (0, _matchIndexedJoins.matchIndexedJoins)(entity, indexedClone, dataSets)
|
|
45
|
+
// Check if there are matching keys for the join condition
|
|
46
|
+
const matchAResult = await (0, _getMatchingIndexes.getMatchingIndexes)(entityA, propertyA, recordData, joinClause, filterJoins, indexed)
|
|
47
|
+
const matchBResult = await (0, _getMatchingIndexes.getMatchingIndexes)(entityB, propertyB, recordData, joinClause, filterJoins, indexed, retrieveMatchedFiles)
|
|
48
|
+
const isIndexed = matchAResult || matchBResult
|
|
49
|
+
if (!isIndexed && firstIteration) {
|
|
50
|
+
reducedJoins.push(joinClause)
|
|
51
|
+
firstIteration = false
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
dataSets[entity][anEntity][joinEntity] = filterJoins[joinEntity]
|
|
55
|
+
}
|
|
56
|
+
parsed.joinClauses = reducedJoins
|
|
57
|
+
return parsed
|
|
58
|
+
}
|
|
59
|
+
exports.getJoinIndexedList = getJoinIndexedList
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.getJoinIndexedList=void 0;var _siFunciona=_interopRequireDefault(require("si-funciona")),_splitEntityProperty=require("./parsers/splitEntityProperty"),_retrieveRecord=require("./retrieveRecord"),_getMatchingIndexes=require("./getMatchingIndexes"),_matchIndexedJoins=require("./matchIndexedJoins"),_restrictIndexedList=require("./restrictIndexedList");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const getJoinIndexedList=async(e,t,r)=>{let i=[];const n={};let s=!0;const o=e.entity,d=e.joinEntity,c=e.joinClauses;for(const e in r[o]){const a=r[o][e];let p={};p[o]=[_siFunciona.default.cloneObject(a)];for(let e of c){let d=_siFunciona.default.cloneObject(n);const{entity:c,property:a}=(0,_splitEntityProperty.splitEntityProperty)(e.propertyA),{entity:u,property:y}=(0,_splitEntityProperty.splitEntityProperty)(e.propertyB);t.hasOwnProperty(c)||(t[c]=await(0,_retrieveRecord.retrieveRecord)(c)),t.hasOwnProperty(u)||(t[u]=await(0,_retrieveRecord.retrieveRecord)(u)),d=(0,_restrictIndexedList.restrictIndexedList)(e,p,d);const l=(0,_matchIndexedJoins.matchIndexedJoins)(o,d,r),_=await(0,_getMatchingIndexes.getMatchingIndexes)(c,a,t,e,p,n),x=await(0,_getMatchingIndexes.getMatchingIndexes)(u,y,t,e,p,n,l);!(_||x)&&s&&(i.push(e),s=!1)}r[o][e][d]=p[d]}return e.joinClauses=i,e};exports.getJoinIndexedList=getJoinIndexedList;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true
|
|
5
|
+
})
|
|
6
|
+
exports.getMatchingIndexes = void 0
|
|
7
|
+
require('core-js/modules/es.array.includes.js')
|
|
8
|
+
const _retrieveIndexes = require('./retrieveIndexes')
|
|
9
|
+
const getMatchingIndexes = async (entity, property, recordData, clause, dataSet, indexed, cb = null) => {
|
|
10
|
+
let isIndexed = false
|
|
11
|
+
for (const key of recordData[entity].keys) {
|
|
12
|
+
if (key.fields.includes(property)) {
|
|
13
|
+
dataSet[entity] = []
|
|
14
|
+
if (!indexed.hasOwnProperty(entity)) {
|
|
15
|
+
indexed[entity] = {}
|
|
16
|
+
}
|
|
17
|
+
if (!indexed[entity].hasOwnProperty(property)) {
|
|
18
|
+
indexed[entity][property] = (await (0, _retrieveIndexes.retrieveIndexes)(entity, [property], recordData))[property]
|
|
19
|
+
}
|
|
20
|
+
if (typeof cb === 'function') {
|
|
21
|
+
await cb(entity, property, recordData, clause, dataSet, indexed)
|
|
22
|
+
}
|
|
23
|
+
isIndexed = true
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return isIndexed
|
|
27
|
+
}
|
|
28
|
+
exports.getMatchingIndexes = getMatchingIndexes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.getMatchingIndexes=void 0,require("core-js/modules/es.array.includes.js");var _retrieveIndexes=require("./retrieveIndexes");const getMatchingIndexes=async(e,r,t,s,n,i,a=null)=>{let d=!1;for(let o of t[e].keys)o.fields.includes(r)&&(n[e]=[],i.hasOwnProperty(e)||(i[e]={}),i[e].hasOwnProperty(r)||(i[e][r]=(await(0,_retrieveIndexes.retrieveIndexes)(e,[r],t))[r]),"function"==typeof a&&await a(e,r,t,s,n,i),d=!0);return d};exports.getMatchingIndexes=getMatchingIndexes;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true
|
|
5
|
+
})
|
|
6
|
+
exports.matchIndexedJoins = void 0
|
|
7
|
+
require('core-js/modules/esnext.iterator.constructor.js')
|
|
8
|
+
require('core-js/modules/esnext.iterator.reduce.js')
|
|
9
|
+
const _siFunciona = _interopRequireDefault(require('si-funciona'))
|
|
10
|
+
const _where = require('../queries/where')
|
|
11
|
+
const _retrieveFile = require('./retrieveFile')
|
|
12
|
+
const _splitEntityProperty = require('./parsers/splitEntityProperty')
|
|
13
|
+
function _interopRequireDefault (e) { return e && e.__esModule ? e : { default: e } }
|
|
14
|
+
const matchIndexedJoins = (entity, indexedClone, dataSets) => async (focusEntity, property, recordData, joinClause, filterJoins, indexed) => {
|
|
15
|
+
const {
|
|
16
|
+
entity: entityA,
|
|
17
|
+
property: propertyA
|
|
18
|
+
} = (0, _splitEntityProperty.splitEntityProperty)(joinClause.propertyA)
|
|
19
|
+
const {
|
|
20
|
+
entity: entityB,
|
|
21
|
+
property: propertyB
|
|
22
|
+
} = (0, _splitEntityProperty.splitEntityProperty)(joinClause.propertyB)
|
|
23
|
+
const properties = [{
|
|
24
|
+
entityFirst: entityA,
|
|
25
|
+
propertyFirst: propertyA,
|
|
26
|
+
entitySecond: entityB,
|
|
27
|
+
propertySecond: propertyB
|
|
28
|
+
}, {
|
|
29
|
+
entityFirst: entityB,
|
|
30
|
+
propertyFirst: propertyB,
|
|
31
|
+
entitySecond: entityA,
|
|
32
|
+
propertySecond: propertyA
|
|
33
|
+
}]
|
|
34
|
+
for (const checkProp of properties) {
|
|
35
|
+
if (!indexedClone.hasOwnProperty(checkProp.entitySecond)) {
|
|
36
|
+
indexedClone[checkProp.entitySecond] = _siFunciona.default.cloneObject(indexed[checkProp.entitySecond])
|
|
37
|
+
}
|
|
38
|
+
const matchedRecords = indexedClone[checkProp.entitySecond][checkProp.propertySecond].reduce((dataA, dataB) => _siFunciona.default.mergeArrays(dataA, (0, _where.where)(indexedClone[checkProp.entityFirst][checkProp.propertyFirst], {
|
|
39
|
+
property: 'value',
|
|
40
|
+
comparator: joinClause.comparator,
|
|
41
|
+
value: dataB.value
|
|
42
|
+
})), [])
|
|
43
|
+
const skipPush = checkProp.entityFirst === entity
|
|
44
|
+
if (!dataSets.hasOwnProperty(checkProp.entityFirst)) {
|
|
45
|
+
dataSets[checkProp.entityFirst] = []
|
|
46
|
+
}
|
|
47
|
+
for (const matchedRecord of matchedRecords) {
|
|
48
|
+
for (const file of matchedRecord.record) {
|
|
49
|
+
let entityRecord = file
|
|
50
|
+
if (typeof file === 'string') {
|
|
51
|
+
entityRecord = await (0, _retrieveFile.retrieveFile)(`${checkProp.entityFirst}/${file}`)
|
|
52
|
+
}
|
|
53
|
+
if (!skipPush) {
|
|
54
|
+
dataSets[checkProp.entityFirst].push(entityRecord)
|
|
55
|
+
}
|
|
56
|
+
filterJoins[checkProp.entityFirst].push(entityRecord)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.matchIndexedJoins = matchIndexedJoins
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.matchIndexedJoins=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.reduce.js");var _siFunciona=_interopRequireDefault(require("si-funciona")),_where=require("../queries/where"),_retrieveFile=require("./retrieveFile"),_splitEntityProperty=require("./parsers/splitEntityProperty");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const matchIndexedJoins=(e,t,r)=>async(i,o,n,s,p,y)=>{const{entity:c,property:u}=(0,_splitEntityProperty.splitEntityProperty)(s.propertyA),{entity:a,property:d}=(0,_splitEntityProperty.splitEntityProperty)(s.propertyB),l=[{entityFirst:c,propertyFirst:u,entitySecond:a,propertySecond:d},{entityFirst:a,propertyFirst:d,entitySecond:c,propertySecond:u}];for(let i of l){t.hasOwnProperty(i.entitySecond)||(t[i.entitySecond]=_siFunciona.default.cloneObject(y[i.entitySecond]));const o=t[i.entitySecond][i.propertySecond].reduce(((e,r)=>_siFunciona.default.mergeArrays(e,(0,_where.where)(t[i.entityFirst][i.propertyFirst],{property:"value",comparator:s.comparator,value:r.value}))),[]);let n=i.entityFirst===e;r.hasOwnProperty(i.entityFirst)||(r[i.entityFirst]=[]);for(let e of o)for(let t of e.record){let e=t;"string"==typeof t&&(e=await(0,_retrieveFile.retrieveFile)(`${i.entityFirst}/${t}`)),n||r[i.entityFirst].push(e),p[i.entityFirst].push(e)}}};exports.matchIndexedJoins=matchIndexedJoins;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true
|
|
5
|
+
})
|
|
6
|
+
exports.mergeJoin = void 0
|
|
7
|
+
require('core-js/modules/esnext.iterator.constructor.js')
|
|
8
|
+
require('core-js/modules/esnext.iterator.map.js')
|
|
9
|
+
const _readEntity = require('../queries/readEntity')
|
|
10
|
+
const _splitEntityProperty = require('./parsers/splitEntityProperty')
|
|
11
|
+
const _where = require('../queries/where')
|
|
12
|
+
const mergeJoin = async (propertyA = '', propertyB = '', dataSets = {}) => {
|
|
13
|
+
const {
|
|
14
|
+
entity: entityA,
|
|
15
|
+
property: propA
|
|
16
|
+
} = (0, _splitEntityProperty.splitEntityProperty)(propertyA)
|
|
17
|
+
const {
|
|
18
|
+
entity: entityB,
|
|
19
|
+
property: propB
|
|
20
|
+
} = (0, _splitEntityProperty.splitEntityProperty)(propertyB)
|
|
21
|
+
dataSets = await (0, _readEntity.readEntity)(entityA, dataSets)
|
|
22
|
+
dataSets = await (0, _readEntity.readEntity)(entityB, dataSets)
|
|
23
|
+
dataSets[entityA] = dataSets[entityA].map(dataA => {
|
|
24
|
+
const matches = (0, _where.where)(dataSets[entityB], {
|
|
25
|
+
property: propB,
|
|
26
|
+
comparator: '=',
|
|
27
|
+
value: dataA[propA]
|
|
28
|
+
})
|
|
29
|
+
if (!matches.length) {
|
|
30
|
+
return dataA
|
|
31
|
+
}
|
|
32
|
+
const mergeMatch = matches[0]
|
|
33
|
+
for (const prop in mergeMatch) {
|
|
34
|
+
if (prop === propB) {
|
|
35
|
+
// Skip the condition property since it is irrelevant
|
|
36
|
+
continue
|
|
37
|
+
}
|
|
38
|
+
dataA[`${entityB}.${prop}`] = mergeMatch[prop]
|
|
39
|
+
}
|
|
40
|
+
return dataA
|
|
41
|
+
})
|
|
42
|
+
return dataSets
|
|
43
|
+
}
|
|
44
|
+
exports.mergeJoin = mergeJoin
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.mergeJoin=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.map.js");var _readEntity=require("../queries/readEntity"),_splitEntityProperty=require("./parsers/splitEntityProperty"),_where=require("../queries/where");const mergeJoin=async(e="",r="",t={})=>{const{entity:i,property:o}=(0,_splitEntityProperty.splitEntityProperty)(e),{entity:n,property:s}=(0,_splitEntityProperty.splitEntityProperty)(r);return t=await(0,_readEntity.readEntity)(i,t),(t=await(0,_readEntity.readEntity)(n,t))[i]=t[i].map((e=>{const r=(0,_where.where)(t[n],{property:s,comparator:"=",value:e[o]});if(!r.length)return e;const i=r[0];for(let r in i)r!==s&&(e[`${n}.${r}`]=i[r]);return e})),t};exports.mergeJoin=mergeJoin;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ParsedQuery } from './parseQuery';
|
|
2
|
+
export type ParsedCommand = string | 'delete' | 'insert' | 'read' | 'update';
|
|
3
|
+
export type ParsedEntity = string;
|
|
4
|
+
/**
|
|
5
|
+
* Extract command clauses from the query.
|
|
6
|
+
* @param parsed
|
|
7
|
+
* @param query
|
|
8
|
+
*/
|
|
9
|
+
export declare const findCommand: (parsed: ParsedQuery, query: string) => string;
|
|
10
|
+
//# sourceMappingURL=findCommand.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true
|
|
5
|
+
})
|
|
6
|
+
exports.findCommand = void 0
|
|
7
|
+
const _removeFromQuery = require('./removeFromQuery')
|
|
8
|
+
const commandMatch = /^(delete|insert|read|update)\s+([a-z0-9_-]+)[\w\n]*/i
|
|
9
|
+
/**
|
|
10
|
+
* Extract command clauses from the query.
|
|
11
|
+
* @param parsed
|
|
12
|
+
* @param query
|
|
13
|
+
*/
|
|
14
|
+
const findCommand = (parsed, query) => {
|
|
15
|
+
const commandFound = query.match(commandMatch)
|
|
16
|
+
parsed.command = undefined
|
|
17
|
+
parsed.entity = undefined
|
|
18
|
+
if (commandFound) {
|
|
19
|
+
parsed.command = commandFound[1]
|
|
20
|
+
parsed.entity = commandFound[2]
|
|
21
|
+
return (0, _removeFromQuery.removeFromQuery)(commandFound[0], query)
|
|
22
|
+
}
|
|
23
|
+
return query
|
|
24
|
+
}
|
|
25
|
+
exports.findCommand = findCommand
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.findCommand=void 0;var _removeFromQuery=require("./removeFromQuery");const commandMatch=/^(delete|insert|read|update)\s+([a-z0-9_-]+)[\w\n]*/i,findCommand=(e,o)=>{const m=o.match(commandMatch);return e.command=void 0,e.entity=void 0,m?(e.command=m[1],e.entity=m[2],(0,_removeFromQuery.removeFromQuery)(m[0],o)):o};exports.findCommand=findCommand;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { LiteralValue } from './parseLiteralValue';
|
|
2
|
+
import { ParsedQuery } from './parseQuery';
|
|
3
|
+
export type ConditionValue = LiteralValue;
|
|
4
|
+
export type ParsedCondition = {
|
|
5
|
+
property: string;
|
|
6
|
+
comparator: string;
|
|
7
|
+
value: ConditionValue;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Extract condition clauses from the query.
|
|
11
|
+
* @param parsed
|
|
12
|
+
* @param query
|
|
13
|
+
*/
|
|
14
|
+
export declare const findConditions: (parsed: ParsedQuery, query: string) => string;
|
|
15
|
+
//# sourceMappingURL=findConditions.d.ts.map
|