json-fs-query 3.1.4 → 3.3.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/README.md +257 -15
- package/browser/jsonFsQuery.js +3884 -5057
- package/browser/jsonFsQuery.min.js +1 -1
- package/dist/data/introspect/alter.d.ts +12 -0
- package/dist/data/introspect/alter.js +304 -0
- package/dist/data/introspect/alter.min.js +1 -0
- package/dist/data/introspect/create.d.ts +10 -0
- package/dist/data/introspect/create.js +9 -23
- package/dist/data/introspect/create.min.js +1 -1
- package/dist/data/introspect/drop.js +7 -15
- package/dist/data/introspect/drop.min.js +1 -1
- package/dist/data/introspect/formatDatabase.d.ts +17 -0
- package/dist/data/introspect/formatDatabase.js +56 -0
- package/dist/data/introspect/formatDatabase.min.js +1 -0
- package/dist/data/introspect/index.d.ts +9 -0
- package/dist/data/introspect/index.js +18 -5
- package/dist/data/introspect/index.min.js +1 -1
- package/dist/data/introspect/packDatabase.d.ts +27 -0
- package/dist/data/introspect/packDatabase.js +113 -0
- package/dist/data/introspect/packDatabase.min.js +1 -0
- package/dist/data/introspect/policies/foreignKeyExists.d.ts +2 -0
- package/dist/data/introspect/policies/foreignKeyExists.js +9 -3
- package/dist/data/introspect/policies/foreignKeyExists.min.js +1 -1
- package/dist/data/introspect/policies/hasDependents.d.ts +3 -3
- package/dist/data/introspect/policies/hasDependents.js +11 -3
- package/dist/data/introspect/policies/hasDependents.min.js +1 -1
- package/dist/data/introspect/policies/keyUnique.d.ts +3 -0
- package/dist/data/introspect/policies/keyUnique.js +10 -0
- package/dist/data/introspect/policies/keyUnique.min.js +1 -1
- package/dist/data/queries/databaseStatements.d.ts +31 -0
- package/dist/data/queries/databaseStatements.js +97 -0
- package/dist/data/queries/databaseStatements.min.js +1 -0
- package/dist/data/queries/deleteEntity.js +35 -19
- package/dist/data/queries/deleteEntity.min.js +1 -1
- package/dist/data/queries/insertEntity.d.ts +8 -0
- package/dist/data/queries/insertEntity.js +340 -43
- package/dist/data/queries/insertEntity.min.js +1 -1
- package/dist/data/queries/joinEntity.d.ts +15 -0
- package/dist/data/queries/joinEntity.js +91 -15
- package/dist/data/queries/joinEntity.min.js +1 -1
- package/dist/data/queries/query.d.ts +2 -1
- package/dist/data/queries/query.js +5 -2
- package/dist/data/queries/query.min.js +1 -1
- package/dist/data/queries/selectFields.d.ts +5 -4
- package/dist/data/queries/selectFields.js +25 -11
- package/dist/data/queries/selectFields.min.js +1 -1
- package/dist/data/queries/updateEntity.js +54 -15
- package/dist/data/queries/updateEntity.min.js +1 -1
- package/dist/data/storage/databases.d.ts +32 -0
- package/dist/data/storage/databases.js +93 -0
- package/dist/data/storage/databases.min.js +1 -0
- package/dist/data/storage/fileExists.d.ts +7 -0
- package/dist/data/storage/fileExists.js +25 -0
- package/dist/data/storage/fileExists.min.js +1 -0
- package/dist/data/storage/index.d.ts +19 -0
- package/dist/data/storage/index.js +124 -0
- package/dist/data/storage/index.min.js +1 -0
- package/dist/data/storage/listFiles.d.ts +8 -0
- package/dist/data/storage/listFiles.js +52 -0
- package/dist/data/storage/listFiles.min.js +1 -0
- package/dist/data/storage/makeDirectory.d.ts +7 -0
- package/dist/data/storage/makeDirectory.js +24 -0
- package/dist/data/storage/makeDirectory.min.js +1 -0
- package/dist/data/storage/nodeFiles.d.ts +6 -0
- package/dist/data/storage/nodeFiles.js +12 -0
- package/dist/data/storage/nodeFiles.min.js +1 -0
- package/dist/data/storage/readCache.d.ts +37 -0
- package/dist/data/storage/readCache.js +117 -0
- package/dist/data/storage/readCache.min.js +1 -0
- package/dist/data/storage/readJson.d.ts +16 -0
- package/dist/data/storage/readJson.js +38 -0
- package/dist/data/storage/readJson.min.js +1 -0
- package/dist/data/storage/removeDirectory.d.ts +8 -0
- package/dist/data/storage/removeDirectory.js +30 -0
- package/dist/data/storage/removeDirectory.min.js +1 -0
- package/dist/data/storage/removeFile.d.ts +8 -0
- package/dist/data/storage/removeFile.js +31 -0
- package/dist/data/storage/removeFile.min.js +1 -0
- package/dist/data/storage/storagePath.d.ts +11 -0
- package/dist/data/storage/storagePath.js +25 -0
- package/dist/data/storage/storagePath.min.js +1 -0
- package/dist/data/storage/writeJson.d.ts +17 -0
- package/dist/data/storage/writeJson.js +37 -0
- package/dist/data/storage/writeJson.min.js +1 -0
- package/dist/data/storage/writeSet.d.ts +64 -0
- package/dist/data/storage/writeSet.js +306 -0
- package/dist/data/storage/writeSet.min.js +1 -0
- package/dist/data/utilities/compareAs.d.ts +1 -0
- package/dist/data/utilities/compareAs.js +2 -2
- package/dist/data/utilities/compareAs.min.js +1 -1
- package/dist/data/utilities/config.d.ts +37 -0
- package/dist/data/utilities/config.js +77 -5
- package/dist/data/utilities/config.min.js +1 -1
- package/dist/data/utilities/databaseLock.d.ts +7 -0
- package/dist/data/utilities/databaseLock.js +19 -4
- package/dist/data/utilities/databaseLock.min.js +1 -1
- package/dist/data/utilities/deregisterRecord.js +4 -10
- package/dist/data/utilities/deregisterRecord.min.js +1 -1
- package/dist/data/utilities/getConditionIndexedList.js +3 -4
- package/dist/data/utilities/getConditionIndexedList.min.js +1 -1
- package/dist/data/utilities/indexBuffer.d.ts +35 -0
- package/dist/data/utilities/indexBuffer.js +139 -0
- package/dist/data/utilities/indexBuffer.min.js +1 -0
- package/dist/data/utilities/indexHas.d.ts +13 -0
- package/dist/data/utilities/indexHas.js +48 -0
- package/dist/data/utilities/indexHas.min.js +1 -0
- package/dist/data/utilities/joinBases.d.ts +29 -0
- package/dist/data/utilities/joinBases.js +128 -0
- package/dist/data/utilities/joinBases.min.js +1 -0
- package/dist/data/utilities/joinKey.d.ts +17 -0
- package/dist/data/utilities/joinKey.js +31 -0
- package/dist/data/utilities/joinKey.min.js +1 -0
- package/dist/data/utilities/keyIndexFiles.d.ts +16 -0
- package/dist/data/utilities/keyIndexFiles.js +60 -0
- package/dist/data/utilities/keyIndexFiles.min.js +1 -0
- package/dist/data/utilities/knownFields.d.ts +26 -0
- package/dist/data/utilities/knownFields.js +128 -0
- package/dist/data/utilities/knownFields.min.js +1 -0
- package/dist/data/utilities/packedTable.d.ts +34 -0
- package/dist/data/utilities/packedTable.js +60 -0
- package/dist/data/utilities/packedTable.min.js +1 -0
- package/dist/data/utilities/parsers/findInsertValues.d.ts +3 -3
- package/dist/data/utilities/parsers/findInsertValues.js +28 -12
- package/dist/data/utilities/parsers/findInsertValues.min.js +1 -1
- package/dist/data/utilities/parsers/maskStrings.js +11 -2
- package/dist/data/utilities/parsers/maskStrings.min.js +1 -1
- package/dist/data/utilities/parsers/parseAlter.d.ts +33 -0
- package/dist/data/utilities/parsers/parseAlter.js +84 -0
- package/dist/data/utilities/parsers/parseAlter.min.js +1 -0
- package/dist/data/utilities/parsers/parseCreate.d.ts +14 -0
- package/dist/data/utilities/parsers/parseCreate.js +13 -5
- package/dist/data/utilities/parsers/parseCreate.min.js +1 -1
- package/dist/data/utilities/parsers/parseDatabaseStatement.d.ts +17 -0
- package/dist/data/utilities/parsers/parseDatabaseStatement.js +82 -0
- package/dist/data/utilities/parsers/parseDatabaseStatement.min.js +1 -0
- package/dist/data/utilities/parsers/parseQuery.d.ts +3 -0
- package/dist/data/utilities/parsers/parseQuery.js +24 -0
- package/dist/data/utilities/parsers/parseQuery.min.js +1 -1
- package/dist/data/utilities/parsers/startsQuery.js +1 -1
- package/dist/data/utilities/parsers/startsQuery.min.js +1 -1
- package/dist/data/utilities/recordExists.js +2 -7
- package/dist/data/utilities/recordExists.min.js +1 -1
- package/dist/data/utilities/registerRecord.js +4 -10
- package/dist/data/utilities/registerRecord.min.js +1 -1
- package/dist/data/utilities/removeFromIndex.js +4 -10
- package/dist/data/utilities/removeFromIndex.min.js +1 -1
- package/dist/data/utilities/retrieveFile.d.ts +5 -0
- package/dist/data/utilities/retrieveFile.js +7 -16
- package/dist/data/utilities/retrieveFile.min.js +1 -1
- package/dist/data/utilities/retrieveFiles.d.ts +15 -0
- package/dist/data/utilities/retrieveFiles.js +48 -0
- package/dist/data/utilities/retrieveFiles.min.js +1 -0
- package/dist/data/utilities/retrieveRecord.d.ts +6 -0
- package/dist/data/utilities/retrieveRecord.js +24 -1
- package/dist/data/utilities/retrieveRecord.min.js +1 -1
- package/dist/data/utilities/retrieveRecords.d.ts +22 -0
- package/dist/data/utilities/retrieveRecords.js +60 -10
- package/dist/data/utilities/retrieveRecords.min.js +1 -1
- package/dist/data/utilities/rowLookup.d.ts +38 -0
- package/dist/data/utilities/rowLookup.js +99 -0
- package/dist/data/utilities/rowLookup.min.js +1 -0
- package/dist/data/utilities/runQuery.js +28 -4
- package/dist/data/utilities/runQuery.min.js +1 -1
- package/dist/data/utilities/semiJoin.d.ts +27 -0
- package/dist/data/utilities/semiJoin.js +97 -0
- package/dist/data/utilities/semiJoin.min.js +1 -0
- package/dist/data/utilities/updateIndex.js +5 -14
- package/dist/data/utilities/updateIndex.min.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +24 -0
- package/dist/index.min.js +1 -1
- package/package.json +10 -4
- package/dist/data/utilities/getJoinIndexedList.d.ts +0 -3
- package/dist/data/utilities/getJoinIndexedList.js +0 -76
- package/dist/data/utilities/getJoinIndexedList.min.js +0 -1
- package/dist/data/utilities/getMatchingIndexes.d.ts +0 -2
- package/dist/data/utilities/getMatchingIndexes.js +0 -28
- package/dist/data/utilities/getMatchingIndexes.min.js +0 -1
- package/dist/data/utilities/matchIndexedJoins.d.ts +0 -2
- package/dist/data/utilities/matchIndexedJoins.js +0 -63
- package/dist/data/utilities/matchIndexedJoins.min.js +0 -1
- package/dist/data/utilities/restrictIndexedList.d.ts +0 -2
- package/dist/data/utilities/restrictIndexedList.js +0 -45
- package/dist/data/utilities/restrictIndexedList.min.js +0 -1
- package/dist/data/utilities/useJoinClause.d.ts +0 -6
- package/dist/data/utilities/useJoinClause.js +0 -57
- package/dist/data/utilities/useJoinClause.min.js +0 -1
|
@@ -7,10 +7,12 @@ exports.query = void 0;
|
|
|
7
7
|
var _parser = require("./parser");
|
|
8
8
|
var _runQuery = require("../utilities/runQuery");
|
|
9
9
|
var _databaseLock = require("../utilities/databaseLock");
|
|
10
|
+
var _storage = require("../storage");
|
|
10
11
|
/**
|
|
11
12
|
* Parse a query string (one query, or several separated by `;`) and run each query in turn, resolving to one result
|
|
12
13
|
* per query. The queries of one call run together, under the database lock: no other call's queries run between
|
|
13
|
-
* them (see withDatabaseLock).
|
|
14
|
+
* them (see withDatabaseLock). Each query is all or nothing: one that fails changes nothing, and the queries before it
|
|
15
|
+
* keep their changes (see withWriteSet).
|
|
14
16
|
* @param queryString
|
|
15
17
|
*/
|
|
16
18
|
const query = async (queryString = '') => {
|
|
@@ -18,7 +20,8 @@ const query = async (queryString = '') => {
|
|
|
18
20
|
return (0, _databaseLock.withDatabaseLock)(async () => {
|
|
19
21
|
const queryResults = [];
|
|
20
22
|
for (const parsed of parsedQueries) {
|
|
21
|
-
|
|
23
|
+
// Each query's changes reach storage together, or not at all if it fails (see withWriteSet)
|
|
24
|
+
const dataSet = await (0, _storage.withWriteSet)(() => (0, _runQuery.runQuery)(parsed));
|
|
22
25
|
queryResults.push(dataSet[parsed.entity]);
|
|
23
26
|
}
|
|
24
27
|
return queryResults;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.query=void 0;var _parser=require("./parser"),_runQuery=require("../utilities/runQuery"),_databaseLock=require("../utilities/databaseLock");const query=async(e="")=>{const r=(0,_parser.parser)(e);return(0,_databaseLock.withDatabaseLock)((async()=>{const e=[];for(const t of r){const r=await(0,_runQuery.runQuery)(t);e.push(r[t.entity])}return e}))};exports.query=query;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.query=void 0;var _parser=require("./parser"),_runQuery=require("../utilities/runQuery"),_databaseLock=require("../utilities/databaseLock"),_storage=require("../storage");const query=async(e="")=>{const r=(0,_parser.parser)(e);return(0,_databaseLock.withDatabaseLock)((async()=>{const e=[];for(const t of r){const r=await(0,_storage.withWriteSet)((()=>(0,_runQuery.runQuery)(t)));e.push(r[t.entity])}return e}))};exports.query=query;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { ParsedSelect } from '../utilities/parsers/findSelects';
|
|
2
2
|
import { Group } from './groupBy';
|
|
3
3
|
/**
|
|
4
|
-
* Shape each row down to only the selected properties (aliased, when given). dataSet is
|
|
5
|
-
* (once groupBy has run) a list of groups, whose rows are shaped the same way at any depth;
|
|
6
|
-
* field and value, selected or not.
|
|
4
|
+
* Shape each row down to only the selected properties (aliased, when given, otherwise named as written). dataSet is
|
|
5
|
+
* either a list of rows, or (once groupBy has run) a list of groups, whose rows are shaped the same way at any depth;
|
|
6
|
+
* the groups keep their field and value, selected or not.
|
|
7
7
|
* @param dataSet
|
|
8
8
|
* @param selectClauses
|
|
9
9
|
* @param grouped Whether dataSet is a list of groups (see groupBy)
|
|
10
|
+
* @param entity The queried record's name, so `<record>.<field>` picks the row's own field
|
|
10
11
|
*/
|
|
11
|
-
export declare const selectFields: (dataSet?: Object[] | Group[], selectClauses?: ParsedSelect[], grouped?: boolean) => Object[] | Group[];
|
|
12
|
+
export declare const selectFields: (dataSet?: Object[] | Group[], selectClauses?: ParsedSelect[], grouped?: boolean, entity?: string) => Object[] | Group[];
|
|
12
13
|
//# sourceMappingURL=selectFields.d.ts.map
|
|
@@ -7,35 +7,49 @@ exports.selectFields = void 0;
|
|
|
7
7
|
require("core-js/modules/esnext.iterator.constructor.js");
|
|
8
8
|
require("core-js/modules/esnext.iterator.map.js");
|
|
9
9
|
require("core-js/modules/esnext.iterator.reduce.js");
|
|
10
|
-
|
|
10
|
+
/**
|
|
11
|
+
* The value a select name picks from a row: the row's own key (a field, a merged record's `<record>.<field>`, or a
|
|
12
|
+
* joined record's rows), or for `<queried record>.<field>`, the row's own field.
|
|
13
|
+
* @param row
|
|
14
|
+
* @param property
|
|
15
|
+
* @param entity - The queried record's name.
|
|
16
|
+
*/
|
|
17
|
+
const pick = (row, property, entity) => {
|
|
18
|
+
if (Object.prototype.hasOwnProperty.call(row, property) || typeof entity === 'undefined' || !property.startsWith(`${entity}.`)) {
|
|
19
|
+
return row[property];
|
|
20
|
+
}
|
|
21
|
+
return row[property.slice(entity.length + 1)];
|
|
22
|
+
};
|
|
23
|
+
const shapeRow = (row, selectClauses, entity) => selectClauses.reduce((shaped, {
|
|
11
24
|
property,
|
|
12
25
|
alias
|
|
13
26
|
}) => {
|
|
14
|
-
shaped[alias || property] = row
|
|
27
|
+
shaped[alias || property] = pick(row, property, entity);
|
|
15
28
|
return shaped;
|
|
16
29
|
}, {});
|
|
17
|
-
const shapeGroup = (group, selectClauses) => group.groups ? {
|
|
30
|
+
const shapeGroup = (group, selectClauses, entity) => group.groups ? {
|
|
18
31
|
...group,
|
|
19
|
-
groups: group.groups.map(inner => shapeGroup(inner, selectClauses))
|
|
32
|
+
groups: group.groups.map(inner => shapeGroup(inner, selectClauses, entity))
|
|
20
33
|
} : {
|
|
21
34
|
...group,
|
|
22
|
-
rows: group.rows.map(row => shapeRow(row, selectClauses))
|
|
35
|
+
rows: group.rows.map(row => shapeRow(row, selectClauses, entity))
|
|
23
36
|
};
|
|
24
37
|
/**
|
|
25
|
-
* Shape each row down to only the selected properties (aliased, when given). dataSet is
|
|
26
|
-
* (once groupBy has run) a list of groups, whose rows are shaped the same way at any depth;
|
|
27
|
-
* field and value, selected or not.
|
|
38
|
+
* Shape each row down to only the selected properties (aliased, when given, otherwise named as written). dataSet is
|
|
39
|
+
* either a list of rows, or (once groupBy has run) a list of groups, whose rows are shaped the same way at any depth;
|
|
40
|
+
* the groups keep their field and value, selected or not.
|
|
28
41
|
* @param dataSet
|
|
29
42
|
* @param selectClauses
|
|
30
43
|
* @param grouped Whether dataSet is a list of groups (see groupBy)
|
|
44
|
+
* @param entity The queried record's name, so `<record>.<field>` picks the row's own field
|
|
31
45
|
*/
|
|
32
|
-
const selectFields = (dataSet = [], selectClauses = [], grouped = false) => {
|
|
46
|
+
const selectFields = (dataSet = [], selectClauses = [], grouped = false, entity) => {
|
|
33
47
|
if (!selectClauses.length) {
|
|
34
48
|
return dataSet;
|
|
35
49
|
}
|
|
36
50
|
if (grouped) {
|
|
37
|
-
return dataSet.map(group => shapeGroup(group, selectClauses));
|
|
51
|
+
return dataSet.map(group => shapeGroup(group, selectClauses, entity));
|
|
38
52
|
}
|
|
39
|
-
return dataSet.map(row => shapeRow(row, selectClauses));
|
|
53
|
+
return dataSet.map(row => shapeRow(row, selectClauses, entity));
|
|
40
54
|
};
|
|
41
55
|
exports.selectFields = selectFields;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.selectFields=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.iterator.reduce.js");const shapeRow=(e,s)=>s.reduce(((s,{property:
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.selectFields=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.iterator.reduce.js");const pick=(e,s,r)=>Object.prototype.hasOwnProperty.call(e,s)||void 0===r||!s.startsWith(`${r}.`)?e[s]:e[s.slice(r.length+1)],shapeRow=(e,s,r)=>s.reduce(((s,{property:o,alias:t})=>(s[t||o]=pick(e,o,r),s)),{}),shapeGroup=(e,s,r)=>e.groups?{...e,groups:e.groups.map((e=>shapeGroup(e,s,r)))}:{...e,rows:e.rows.map((e=>shapeRow(e,s,r)))},selectFields=(e=[],s=[],r=!1,o)=>s.length?r?e.map((e=>shapeGroup(e,s,o))):e.map((e=>shapeRow(e,s,o))):e;exports.selectFields=selectFields;
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.updateEntity = void 0;
|
|
7
|
-
require("core-js/modules/es.json.stringify.js");
|
|
8
7
|
require("core-js/modules/esnext.iterator.constructor.js");
|
|
9
8
|
require("core-js/modules/esnext.iterator.find.js");
|
|
10
9
|
require("core-js/modules/esnext.iterator.map.js");
|
|
@@ -22,21 +21,30 @@ var _foreignKeyExists = require("../introspect/policies/foreignKeyExists");
|
|
|
22
21
|
var _hasDependents = require("../introspect/policies/hasDependents");
|
|
23
22
|
var _splitEntityProperty = require("../utilities/parsers/splitEntityProperty");
|
|
24
23
|
var _config = require("../utilities/config");
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
var _keyIndexFiles = require("../utilities/keyIndexFiles");
|
|
25
|
+
var _storage = require("../storage");
|
|
26
|
+
var _packedTable = require("../utilities/packedTable");
|
|
27
|
+
var _knownFields = require("../utilities/knownFields");
|
|
28
28
|
/**
|
|
29
29
|
* Same reasoning as deleteEntity: a record object carries no memory of which entry file it came
|
|
30
|
-
* from, so
|
|
31
|
-
*
|
|
30
|
+
* from, so find the file whose primary key value(s) match - a single field, or a composite of
|
|
31
|
+
* several for a multi-field primary key. The primary key's index says which file that is; the file
|
|
32
|
+
* is read to confirm it, and without an index (or when it leads nowhere) every entry is looked at
|
|
33
|
+
* in turn, as before.
|
|
32
34
|
* @param record
|
|
33
35
|
* @param primaryKey
|
|
34
36
|
* @param primaryValue
|
|
35
37
|
*/
|
|
36
38
|
const findEntryFile = async (record, primaryKey, primaryValue) => {
|
|
39
|
+
const type = (0, _fieldType.keyValueType)(record, primaryKey);
|
|
40
|
+
const isMatch = async fileName => (0, _compareAs.sameValue)(type, (0, _computeKeyValue.computeKeyValue)(primaryKey.fields, await (0, _retrieveFile.retrieveFile)(`${record.path}/${fileName}`)), primaryValue);
|
|
41
|
+
for (const fileName of (await (0, _keyIndexFiles.keyIndexFiles)(record, primaryKey, value => (0, _compareAs.sameValue)(type, value, primaryValue))) ?? []) {
|
|
42
|
+
if (await isMatch(fileName)) {
|
|
43
|
+
return fileName;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
37
46
|
for (const fileName of record.entries) {
|
|
38
|
-
|
|
39
|
-
if ((0, _compareAs.sameValue)((0, _fieldType.keyValueType)(record, primaryKey), (0, _computeKeyValue.computeKeyValue)(primaryKey.fields, data), primaryValue)) {
|
|
47
|
+
if (await isMatch(fileName)) {
|
|
40
48
|
return fileName;
|
|
41
49
|
}
|
|
42
50
|
}
|
|
@@ -68,7 +76,8 @@ const assertUniqueForUpdate = async (entity, record, oldData, newData, newValues
|
|
|
68
76
|
continue;
|
|
69
77
|
}
|
|
70
78
|
const checkKeys = key.fields.map(field => newData[field]);
|
|
71
|
-
|
|
79
|
+
// A null, or a field the row doesn't have (left out, or removed by this update), is never a duplicate
|
|
80
|
+
if (checkKeys.some(value => value === null || typeof value === 'undefined')) {
|
|
72
81
|
continue;
|
|
73
82
|
}
|
|
74
83
|
const isUnique = await (0, _keyUnique.keyUnique)(entity, key.fields, checkKeys);
|
|
@@ -93,7 +102,8 @@ const assertForeignKeysForUpdate = async (entity, record, oldData, newValues) =>
|
|
|
93
102
|
continue;
|
|
94
103
|
}
|
|
95
104
|
const field = key.fields[0];
|
|
96
|
-
|
|
105
|
+
// A null, or a field the update removes (undefined), references nothing
|
|
106
|
+
if (!Object.prototype.hasOwnProperty.call(newValues, field) || newValues[field] === null || typeof newValues[field] === 'undefined' || (0, _compareAs.sameValue)((0, _fieldType.fieldType)(record, field), newValues[field], oldData[field])) {
|
|
97
107
|
continue;
|
|
98
108
|
}
|
|
99
109
|
const {
|
|
@@ -163,7 +173,7 @@ const assertUniqueWithinUpdate = (entity, record, planned, newValues) => {
|
|
|
163
173
|
oldData,
|
|
164
174
|
newData
|
|
165
175
|
} of planned) {
|
|
166
|
-
if (!keyFieldsChanged(record, key, oldData, newValues) || key.fields.some(field => newData[field] === null)) {
|
|
176
|
+
if (!keyFieldsChanged(record, key, oldData, newValues) || key.fields.some(field => newData[field] === null || typeof newData[field] === 'undefined')) {
|
|
167
177
|
continue;
|
|
168
178
|
}
|
|
169
179
|
const value = (0, _computeKeyValue.computeKeyValue)(key.fields, newData);
|
|
@@ -186,6 +196,11 @@ const assertRequiredFields = (entity, record, newData) => {
|
|
|
186
196
|
* of the merged record - a field whose already-stored value doesn't match its declared type
|
|
187
197
|
* (nothing enforced this before typeCheck() existed) must not block an update that never touches
|
|
188
198
|
* that field.
|
|
199
|
+
*
|
|
200
|
+
* A null for an optional field that isn't nullable means the field is removed from the row (the
|
|
201
|
+
* field can't hold null, so this is the only thing it can mean, and the only way to clear one):
|
|
202
|
+
* it's kept as undefined here, so the key checks and indexes see the field change, and removed from
|
|
203
|
+
* the row that's written (see withoutRemoved).
|
|
189
204
|
* @param record
|
|
190
205
|
* @param values
|
|
191
206
|
*/
|
|
@@ -193,19 +208,40 @@ const applyFieldTypes = (record, values) => {
|
|
|
193
208
|
const typedValues = Object.assign({}, values);
|
|
194
209
|
for (const field of record.definition) {
|
|
195
210
|
if (Object.prototype.hasOwnProperty.call(typedValues, field.name)) {
|
|
196
|
-
typedValues[field.name] = (0, _typeCheck.typeCheck)(field.type, typedValues[field.name], field.nullable);
|
|
211
|
+
typedValues[field.name] = typedValues[field.name] === null && field.optional && !field.nullable ? undefined : (0, _typeCheck.typeCheck)(field.type, typedValues[field.name], field.nullable);
|
|
197
212
|
}
|
|
198
213
|
}
|
|
199
214
|
return typedValues;
|
|
200
215
|
};
|
|
216
|
+
/**
|
|
217
|
+
* A row without the fields an update removes (those it set to undefined, see applyFieldTypes).
|
|
218
|
+
* @param row
|
|
219
|
+
* @param typedValues
|
|
220
|
+
*/
|
|
221
|
+
const withoutRemoved = (row, typedValues) => {
|
|
222
|
+
const kept = Object.assign({}, row);
|
|
223
|
+
for (const field of Object.keys(typedValues)) {
|
|
224
|
+
if (typeof typedValues[field] === 'undefined') {
|
|
225
|
+
delete kept[field];
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return kept;
|
|
229
|
+
};
|
|
201
230
|
const updateEntity = async (entity = '', values = {}, dataSet = {}) => {
|
|
202
|
-
const databasePath = (0, _config.getSetting)('databasePath', 'database/');
|
|
203
231
|
const record = await (0, _retrieveRecord.retrieveRecord)(entity);
|
|
204
232
|
const primaryKey = record.keys.find(key => key.type === 'primary');
|
|
205
233
|
if (!primaryKey) {
|
|
206
234
|
throw new Error(`Cannot update "${entity}" without a primary key`);
|
|
207
235
|
}
|
|
236
|
+
// A field the record doesn't define would otherwise be stored outside its definition
|
|
237
|
+
(0, _knownFields.assertFieldsDefined)(entity, record, Object.keys(values || {}), 'set');
|
|
208
238
|
const typedValues = applyFieldTypes(record, values);
|
|
239
|
+
// A row is found by its primary key, so none of its fields can be cleared (an optional one could be, by null)
|
|
240
|
+
for (const field of primaryKey.fields) {
|
|
241
|
+
if (Object.prototype.hasOwnProperty.call(typedValues, field) && typeof typedValues[field] === 'undefined') {
|
|
242
|
+
throw new Error(`Cannot clear "${field}" on ${entity}: it's part of the primary key`);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
209
245
|
// Check every row first and write only once all of them pass, so a row that fails leaves the others unchanged too
|
|
210
246
|
const planned = [];
|
|
211
247
|
for (const row of dataSet[entity] || []) {
|
|
@@ -218,7 +254,7 @@ const updateEntity = async (entity = '', values = {}, dataSet = {}) => {
|
|
|
218
254
|
continue;
|
|
219
255
|
}
|
|
220
256
|
const oldData = await (0, _retrieveFile.retrieveFile)(`${record.path}/${fileName}`);
|
|
221
|
-
const newData = Object.assign({}, oldData, typedValues);
|
|
257
|
+
const newData = withoutRemoved(Object.assign({}, oldData, typedValues), typedValues);
|
|
222
258
|
await assertUniqueForUpdate(entity, record, oldData, newData, typedValues);
|
|
223
259
|
await assertForeignKeysForUpdate(entity, record, oldData, typedValues);
|
|
224
260
|
await assertNoDependentsForUpdate(entity, record, primaryKey, oldData, typedValues);
|
|
@@ -230,13 +266,16 @@ const updateEntity = async (entity = '', values = {}, dataSet = {}) => {
|
|
|
230
266
|
});
|
|
231
267
|
}
|
|
232
268
|
assertUniqueWithinUpdate(entity, record, planned, typedValues);
|
|
269
|
+
if (planned.length) {
|
|
270
|
+
await (0, _packedTable.discardPacked)(record.path);
|
|
271
|
+
}
|
|
233
272
|
for (const {
|
|
234
273
|
fileName,
|
|
235
274
|
oldData,
|
|
236
275
|
newData
|
|
237
276
|
} of planned) {
|
|
238
277
|
await reconcileIndexes(record, oldData, newData, typedValues, fileName);
|
|
239
|
-
await
|
|
278
|
+
await (0, _storage.writeJson)(`${record.path}/${fileName}`, newData);
|
|
240
279
|
}
|
|
241
280
|
dataSet[entity] = planned.map(({
|
|
242
281
|
newData
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.updateEntity=void 0,require("core-js/modules/
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.updateEntity=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.iterator.some.js");var _retrieveRecord=require("../utilities/retrieveRecord"),_retrieveFile=require("../utilities/retrieveFile"),_updateIndex=require("../utilities/updateIndex"),_removeFromIndex=require("../utilities/removeFromIndex"),_computeKeyValue=require("../utilities/computeKeyValue"),_fieldType=require("../utilities/fieldType"),_compareAs=require("../utilities/compareAs"),_keyUnique=require("../introspect/policies/keyUnique"),_typeCheck=require("../introspect/policies/typeCheck"),_foreignKeyExists=require("../introspect/policies/foreignKeyExists"),_hasDependents=require("../introspect/policies/hasDependents"),_splitEntityProperty=require("../utilities/parsers/splitEntityProperty"),_config=require("../utilities/config"),_keyIndexFiles=require("../utilities/keyIndexFiles"),_storage=require("../storage"),_packedTable=require("../utilities/packedTable"),_knownFields=require("../utilities/knownFields");const findEntryFile=async(e,t,i)=>{const r=(0,_fieldType.keyValueType)(e,t),o=async o=>(0,_compareAs.sameValue)(r,(0,_computeKeyValue.computeKeyValue)(t.fields,await(0,_retrieveFile.retrieveFile)(`${e.path}/${o}`)),i);for(const s of await(0,_keyIndexFiles.keyIndexFiles)(e,t,(e=>(0,_compareAs.sameValue)(r,e,i)))??[])if(await o(s))return s;for(const t of e.entries)if(await o(t))return t;return null},keyFieldsChanged=(e,t,i,r)=>t.fields.some((t=>Object.prototype.hasOwnProperty.call(r,t)&&!(0,_compareAs.sameValue)((0,_fieldType.fieldType)(e,t),r[t],i[t]))),assertUniqueForUpdate=async(e,t,i,r,o)=>{for(const s of t.keys){if("primary"!==s.type&&"unique"!==s.type||!keyFieldsChanged(t,s,i,o))continue;const n=s.fields.map((e=>r[e]));if(n.some((e=>null==e)))continue;if(!await(0,_keyUnique.keyUnique)(e,s.fields,n))throw new Error(`Duplicate value for ${s.type} key "${s.fields.join(", ")}" on ${e}`)}},assertForeignKeysForUpdate=async(e,t,i,r)=>{for(const o of t.keys){if("foreign"!==o.type||1!==o.fields.length||!o.references||1!==o.references.length)continue;const s=o.fields[0];if(!Object.prototype.hasOwnProperty.call(r,s)||null===r[s]||void 0===r[s]||(0,_compareAs.sameValue)((0,_fieldType.fieldType)(t,s),r[s],i[s]))continue;const{entity:n,property:a}=(0,_splitEntityProperty.splitEntityProperty)(o.references[0].fields[0]);if(!await(0,_foreignKeyExists.foreignKeyExists)(n,a,r[s]))throw new Error(`Foreign key "${s}" on ${e} references a nonexistent ${n}.${a} = ${r[s]}`)}},assertNoDependentsForUpdate=async(e,t,i,r,o)=>{if(!(0,_config.getSetting)("enforceForeignKeys",!0)||1!==i.fields.length||!keyFieldsChanged(t,i,r,o))return;const s=i.fields[0];if(await(0,_hasDependents.hasDependents)(e,s,r[s]))throw new Error(`Cannot update "${e}" where "${s}" = ${r[s]} - other records still reference it`)},reconcileIndexes=async(e,t,i,r,o)=>{for(const s of e.keys)keyFieldsChanged(e,s,t,r)&&(await(0,_removeFromIndex.removeFromIndex)(e.path,s,(0,_computeKeyValue.computeKeyValue)(s.fields,t),o,(0,_fieldType.keyValueType)(e,s)),await(0,_updateIndex.updateIndex)(e.path,s,(0,_computeKeyValue.computeKeyValue)(s.fields,i),o,(0,_fieldType.keyValueType)(e,s)))},assertUniqueWithinUpdate=(e,t,i,r)=>{for(const o of t.keys){if("primary"!==o.type&&"unique"!==o.type)continue;const s=[];for(const{oldData:n,newData:a}of i){if(!keyFieldsChanged(t,o,n,r)||o.fields.some((e=>null===a[e]||void 0===a[e])))continue;const i=(0,_computeKeyValue.computeKeyValue)(o.fields,a);if(s.some((e=>(0,_compareAs.sameValue)((0,_fieldType.keyValueType)(t,o),e,i))))throw new Error(`Duplicate value for ${o.type} key "${o.fields.join(", ")}" on ${e}`);s.push(i)}}},assertRequiredFields=(e,t,i)=>{for(const r of t.definition)if(!r.optional&&void 0===i[r.name])throw new Error(`Missing required field "${r.name}" for ${e}`)},applyFieldTypes=(e,t)=>{const i=Object.assign({},t);for(const t of e.definition)Object.prototype.hasOwnProperty.call(i,t.name)&&(i[t.name]=null===i[t.name]&&t.optional&&!t.nullable?void 0:(0,_typeCheck.typeCheck)(t.type,i[t.name],t.nullable));return i},withoutRemoved=(e,t)=>{const i=Object.assign({},e);for(const e of Object.keys(t))void 0===t[e]&&delete i[e];return i},updateEntity=async(e="",t={},i={})=>{const r=await(0,_retrieveRecord.retrieveRecord)(e),o=r.keys.find((e=>"primary"===e.type));if(!o)throw new Error(`Cannot update "${e}" without a primary key`);(0,_knownFields.assertFieldsDefined)(e,r,Object.keys(t||{}),"set");const s=applyFieldTypes(r,t);for(const t of o.fields)if(Object.prototype.hasOwnProperty.call(s,t)&&void 0===s[t])throw new Error(`Cannot clear "${t}" on ${e}: it's part of the primary key`);const n=[];for(const t of i[e]||[]){const i=await findEntryFile(r,o,(0,_computeKeyValue.computeKeyValue)(o.fields,t));if(!i)throw new Error(`Could not find entry for ${e} where "${o.fields.join(", ")}" = ${(0,_computeKeyValue.computeKeyValue)(o.fields,t)}`);if(n.some((e=>e.fileName===i)))continue;const a=await(0,_retrieveFile.retrieveFile)(`${r.path}/${i}`),l=withoutRemoved(Object.assign({},a,s),s);await assertUniqueForUpdate(e,r,a,l,s),await assertForeignKeysForUpdate(e,r,a,s),await assertNoDependentsForUpdate(e,r,o,a,s),assertRequiredFields(e,r,l),n.push({fileName:i,oldData:a,newData:l})}assertUniqueWithinUpdate(e,r,n,s),n.length&&await(0,_packedTable.discardPacked)(r.path);for(const{fileName:e,oldData:t,newData:i}of n)await reconcileIndexes(r,t,i,s,e),await(0,_storage.writeJson)(`${r.path}/${e}`,i);return i[e]=n.map((({newData:e})=>e)),i};exports.updateEntity=updateEntity;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where something in the folder holding the databases is (see databasesFolder), as storagePath gives it for a database:
|
|
3
|
+
* on disk in Node, behind relativePath over fetch() in a browser.
|
|
4
|
+
* @param path - A path inside that folder, such as `__DATABASES.json` or a database's name.
|
|
5
|
+
*/
|
|
6
|
+
export declare const databasesLocation: (path?: string) => string;
|
|
7
|
+
/**
|
|
8
|
+
* The databases' names, in the order they were created, from `__DATABASES.json` in the folder holding them (a list, so
|
|
9
|
+
* a browser can read it too: it can't list a folder). No list yet means no databases.
|
|
10
|
+
*/
|
|
11
|
+
export declare const readDatabaseList: () => Promise<string[]>;
|
|
12
|
+
/**
|
|
13
|
+
* Replace the list of databases. Node only.
|
|
14
|
+
* @param names
|
|
15
|
+
*/
|
|
16
|
+
export declare const writeDatabaseList: (names: string[]) => Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Whether a database's folder exists. Node only.
|
|
19
|
+
* @param name
|
|
20
|
+
*/
|
|
21
|
+
export declare const databaseFolderExists: (name: string) => boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Create a database's (empty) folder. Node only.
|
|
24
|
+
* @param name
|
|
25
|
+
*/
|
|
26
|
+
export declare const makeDatabaseFolder: (name: string) => Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Delete a database's folder and everything in it, and forget anything read from it. Node only.
|
|
29
|
+
* @param name
|
|
30
|
+
*/
|
|
31
|
+
export declare const removeDatabaseFolder: (name: string) => Promise<void>;
|
|
32
|
+
//# sourceMappingURL=databases.d.ts.map
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
require("core-js/modules/esnext.weak-map.delete-all.js");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.writeDatabaseList = exports.removeDatabaseFolder = exports.readDatabaseList = exports.makeDatabaseFolder = exports.databasesLocation = exports.databaseFolderExists = void 0;
|
|
8
|
+
require("core-js/modules/es.json.stringify.js");
|
|
9
|
+
var jsEnv = _interopRequireWildcard(require("browser-or-node"));
|
|
10
|
+
var _config = require("../utilities/config");
|
|
11
|
+
var _nodeFiles = require("./nodeFiles");
|
|
12
|
+
var _readCache = require("./readCache");
|
|
13
|
+
var _writeSet = require("./writeSet");
|
|
14
|
+
var e;
|
|
15
|
+
function _interopRequireWildcard(t, r) { if (!r && t && t.__esModule) return t; var n, a, o = Object.defineProperty, f = { __proto__: null, default: t }; if (Object(t) !== t) return f; if (e || "function" != typeof WeakMap || (e = new WeakMap()), e) { if (e.has(t)) return e.get(t); e.set(t, f); } for (a in t) "default" !== a && {}.hasOwnProperty.call(t, a) && ((n = o && Object.getOwnPropertyDescriptor(t, a)) && (n.get || n.set) ? o(f, a, n) : f[a] = t[a]); return f; }
|
|
16
|
+
/**
|
|
17
|
+
* Where something in the folder holding the databases is (see databasesFolder), as storagePath gives it for a database:
|
|
18
|
+
* on disk in Node, behind relativePath over fetch() in a browser.
|
|
19
|
+
* @param path - A path inside that folder, such as `__DATABASES.json` or a database's name.
|
|
20
|
+
*/
|
|
21
|
+
const databasesLocation = (path = '') => {
|
|
22
|
+
const relativePath = jsEnv.isBrowser ? (0, _config.getSetting)('relativePath', '') : '';
|
|
23
|
+
return `${relativePath}${(0, _config.databasesFolder)()}${path}`;
|
|
24
|
+
};
|
|
25
|
+
exports.databasesLocation = databasesLocation;
|
|
26
|
+
const listLocation = () => databasesLocation('__DATABASES.json');
|
|
27
|
+
/**
|
|
28
|
+
* The databases' names, in the order they were created, from `__DATABASES.json` in the folder holding them (a list, so
|
|
29
|
+
* a browser can read it too: it can't list a folder). No list yet means no databases.
|
|
30
|
+
*/
|
|
31
|
+
const readDatabaseList = async () => {
|
|
32
|
+
let text;
|
|
33
|
+
try {
|
|
34
|
+
text = jsEnv.isNode ? await (0, _nodeFiles.nodeFiles)().readFile(listLocation(), 'utf8') : await fetch(listLocation()).then(response => response.ok === false ? '[]' : response.text());
|
|
35
|
+
} catch (error) {
|
|
36
|
+
if (jsEnv.isNode && error?.code !== 'ENOENT') {
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const names = JSON.parse(text);
|
|
43
|
+
return Array.isArray(names) ? names : [];
|
|
44
|
+
} catch (error) {
|
|
45
|
+
// A static host answers a missing file with a page that isn't JSON
|
|
46
|
+
if (!jsEnv.isNode) {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
throw new Error(`Could not read ${listLocation()}: ${error.message}`);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Replace the list of databases. Node only.
|
|
54
|
+
* @param names
|
|
55
|
+
*/
|
|
56
|
+
exports.readDatabaseList = readDatabaseList;
|
|
57
|
+
const writeDatabaseList = async names => {
|
|
58
|
+
await (0, _nodeFiles.nodeFiles)().mkdir(databasesLocation(), {
|
|
59
|
+
recursive: true
|
|
60
|
+
});
|
|
61
|
+
await (0, _writeSet.writeAtomically)(listLocation(), JSON.stringify(names));
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Whether a database's folder exists. Node only.
|
|
65
|
+
* @param name
|
|
66
|
+
*/
|
|
67
|
+
exports.writeDatabaseList = writeDatabaseList;
|
|
68
|
+
const databaseFolderExists = name => require('fs').existsSync(databasesLocation(name));
|
|
69
|
+
/**
|
|
70
|
+
* Create a database's (empty) folder. Node only.
|
|
71
|
+
* @param name
|
|
72
|
+
*/
|
|
73
|
+
exports.databaseFolderExists = databaseFolderExists;
|
|
74
|
+
const makeDatabaseFolder = async name => {
|
|
75
|
+
await (0, _nodeFiles.nodeFiles)().mkdir(databasesLocation(name), {
|
|
76
|
+
recursive: true
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Delete a database's folder and everything in it, and forget anything read from it. Node only.
|
|
81
|
+
* @param name
|
|
82
|
+
*/
|
|
83
|
+
exports.makeDatabaseFolder = makeDatabaseFolder;
|
|
84
|
+
const removeDatabaseFolder = async name => {
|
|
85
|
+
const location = databasesLocation(name);
|
|
86
|
+
(0, _readCache.cacheRemove)(location, true);
|
|
87
|
+
await (0, _nodeFiles.nodeFiles)().rm(location, {
|
|
88
|
+
recursive: true,
|
|
89
|
+
force: true
|
|
90
|
+
});
|
|
91
|
+
(0, _readCache.cacheRemove)(location, true);
|
|
92
|
+
};
|
|
93
|
+
exports.removeDatabaseFolder = removeDatabaseFolder;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";require("core-js/modules/esnext.weak-map.delete-all.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.writeDatabaseList=exports.removeDatabaseFolder=exports.readDatabaseList=exports.makeDatabaseFolder=exports.databasesLocation=exports.databaseFolderExists=void 0,require("core-js/modules/es.json.stringify.js");var e,jsEnv=_interopRequireWildcard(require("browser-or-node")),_config=require("../utilities/config"),_nodeFiles=require("./nodeFiles"),_readCache=require("./readCache"),_writeSet=require("./writeSet");function _interopRequireWildcard(a,t){if(!t&&a&&a.__esModule)return a;var s,r,o=Object.defineProperty,i={__proto__:null,default:a};if(Object(a)!==a)return i;if(e||"function"!=typeof WeakMap||(e=new WeakMap),e){if(e.has(a))return e.get(a);e.set(a,i)}for(r in a)"default"!==r&&{}.hasOwnProperty.call(a,r)&&((s=o&&Object.getOwnPropertyDescriptor(a,r))&&(s.get||s.set)?o(i,r,s):i[r]=a[r]);return i}const databasesLocation=(e="")=>`${jsEnv.isBrowser?(0,_config.getSetting)("relativePath",""):""}${(0,_config.databasesFolder)()}${e}`;exports.databasesLocation=databasesLocation;const listLocation=()=>databasesLocation("__DATABASES.json"),readDatabaseList=async()=>{let e;try{e=jsEnv.isNode?await(0,_nodeFiles.nodeFiles)().readFile(listLocation(),"utf8"):await fetch(listLocation()).then((e=>!1===e.ok?"[]":e.text()))}catch(e){if(jsEnv.isNode&&"ENOENT"!==e?.code)throw e;return[]}try{const a=JSON.parse(e);return Array.isArray(a)?a:[]}catch(e){if(!jsEnv.isNode)return[];throw new Error(`Could not read ${listLocation()}: ${e.message}`)}};exports.readDatabaseList=readDatabaseList;const writeDatabaseList=async e=>{await(0,_nodeFiles.nodeFiles)().mkdir(databasesLocation(),{recursive:!0}),await(0,_writeSet.writeAtomically)(listLocation(),JSON.stringify(e))};exports.writeDatabaseList=writeDatabaseList;const databaseFolderExists=e=>require("fs").existsSync(databasesLocation(e));exports.databaseFolderExists=databaseFolderExists;const makeDatabaseFolder=async e=>{await(0,_nodeFiles.nodeFiles)().mkdir(databasesLocation(e),{recursive:!0})};exports.makeDatabaseFolder=makeDatabaseFolder;const removeDatabaseFolder=async e=>{const a=databasesLocation(e);(0,_readCache.cacheRemove)(a,!0),await(0,_nodeFiles.nodeFiles)().rm(a,{recursive:!0,force:!0}),(0,_readCache.cacheRemove)(a,!0)};exports.removeDatabaseFolder=removeDatabaseFolder;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a file (or folder) of the database exists, counting what the running statement has written or deleted so
|
|
3
|
+
* far (see withWriteSet). Node only, like the schema statements that use it.
|
|
4
|
+
* @param path - A path inside the database, such as `users.json`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const fileExists: (path: string) => boolean;
|
|
7
|
+
//# sourceMappingURL=fileExists.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.fileExists = void 0;
|
|
7
|
+
var _storagePath = require("./storagePath");
|
|
8
|
+
var _writeSet = require("./writeSet");
|
|
9
|
+
/**
|
|
10
|
+
* Whether a file (or folder) of the database exists, counting what the running statement has written or deleted so
|
|
11
|
+
* far (see withWriteSet). Node only, like the schema statements that use it.
|
|
12
|
+
* @param path - A path inside the database, such as `users.json`.
|
|
13
|
+
*/
|
|
14
|
+
const fileExists = path => {
|
|
15
|
+
const location = (0, _storagePath.storagePath)(path);
|
|
16
|
+
const pending = (0, _writeSet.pendingExists)(location);
|
|
17
|
+
if (pending !== undefined) {
|
|
18
|
+
return pending;
|
|
19
|
+
}
|
|
20
|
+
const {
|
|
21
|
+
existsSync
|
|
22
|
+
} = require('fs');
|
|
23
|
+
return existsSync(location);
|
|
24
|
+
};
|
|
25
|
+
exports.fileExists = fileExists;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.fileExists=void 0;var _storagePath=require("./storagePath"),_writeSet=require("./writeSet");const fileExists=e=>{const t=(0,_storagePath.storagePath)(e),s=(0,_writeSet.pendingExists)(t);if(void 0!==s)return s;const{existsSync:r}=require("fs");return r(t)};exports.fileExists=fileExists;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The storage layer: every file json-fs-query reads, writes or deletes goes through these functions, and nothing else
|
|
3
|
+
* touches `fs` or `fetch()`. Paths given to them are inside the database (see storagePath).
|
|
4
|
+
*
|
|
5
|
+
* Today there is one backend, JSON files (on disk in Node, over fetch() in a browser). Keeping it behind these few
|
|
6
|
+
* functions is what lets a read cache, batched writes and other storage backends come later without touching queries.
|
|
7
|
+
*/
|
|
8
|
+
export { storagePath } from './storagePath';
|
|
9
|
+
export { readJson, readText } from './readJson';
|
|
10
|
+
export { writeJson, jsonText } from './writeJson';
|
|
11
|
+
export { makeDirectory } from './makeDirectory';
|
|
12
|
+
export { removeFile } from './removeFile';
|
|
13
|
+
export { removeDirectory } from './removeDirectory';
|
|
14
|
+
export { fileExists } from './fileExists';
|
|
15
|
+
export { listFiles } from './listFiles';
|
|
16
|
+
export { databasesLocation, readDatabaseList, writeDatabaseList, databaseFolderExists, makeDatabaseFolder, removeDatabaseFolder } from './databases';
|
|
17
|
+
export { withReadCache } from './readCache';
|
|
18
|
+
export { withWriteSet } from './writeSet';
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "databaseFolderExists", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _databases.databaseFolderExists;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "databasesLocation", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _databases.databasesLocation;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "fileExists", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _fileExists.fileExists;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "jsonText", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _writeJson.jsonText;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(exports, "listFiles", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return _listFiles.listFiles;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(exports, "makeDatabaseFolder", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return _databases.makeDatabaseFolder;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(exports, "makeDirectory", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function () {
|
|
45
|
+
return _makeDirectory.makeDirectory;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(exports, "readDatabaseList", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function () {
|
|
51
|
+
return _databases.readDatabaseList;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
Object.defineProperty(exports, "readJson", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function () {
|
|
57
|
+
return _readJson.readJson;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
Object.defineProperty(exports, "readText", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function () {
|
|
63
|
+
return _readJson.readText;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
Object.defineProperty(exports, "removeDatabaseFolder", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
get: function () {
|
|
69
|
+
return _databases.removeDatabaseFolder;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
Object.defineProperty(exports, "removeDirectory", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
get: function () {
|
|
75
|
+
return _removeDirectory.removeDirectory;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
Object.defineProperty(exports, "removeFile", {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
get: function () {
|
|
81
|
+
return _removeFile.removeFile;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
Object.defineProperty(exports, "storagePath", {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
get: function () {
|
|
87
|
+
return _storagePath.storagePath;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
Object.defineProperty(exports, "withReadCache", {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
get: function () {
|
|
93
|
+
return _readCache.withReadCache;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
Object.defineProperty(exports, "withWriteSet", {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
get: function () {
|
|
99
|
+
return _writeSet.withWriteSet;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
Object.defineProperty(exports, "writeDatabaseList", {
|
|
103
|
+
enumerable: true,
|
|
104
|
+
get: function () {
|
|
105
|
+
return _databases.writeDatabaseList;
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
Object.defineProperty(exports, "writeJson", {
|
|
109
|
+
enumerable: true,
|
|
110
|
+
get: function () {
|
|
111
|
+
return _writeJson.writeJson;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
var _storagePath = require("./storagePath");
|
|
115
|
+
var _readJson = require("./readJson");
|
|
116
|
+
var _writeJson = require("./writeJson");
|
|
117
|
+
var _makeDirectory = require("./makeDirectory");
|
|
118
|
+
var _removeFile = require("./removeFile");
|
|
119
|
+
var _removeDirectory = require("./removeDirectory");
|
|
120
|
+
var _fileExists = require("./fileExists");
|
|
121
|
+
var _listFiles = require("./listFiles");
|
|
122
|
+
var _databases = require("./databases");
|
|
123
|
+
var _readCache = require("./readCache");
|
|
124
|
+
var _writeSet = require("./writeSet");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"databaseFolderExists",{enumerable:!0,get:function(){return _databases.databaseFolderExists}}),Object.defineProperty(exports,"databasesLocation",{enumerable:!0,get:function(){return _databases.databasesLocation}}),Object.defineProperty(exports,"fileExists",{enumerable:!0,get:function(){return _fileExists.fileExists}}),Object.defineProperty(exports,"jsonText",{enumerable:!0,get:function(){return _writeJson.jsonText}}),Object.defineProperty(exports,"listFiles",{enumerable:!0,get:function(){return _listFiles.listFiles}}),Object.defineProperty(exports,"makeDatabaseFolder",{enumerable:!0,get:function(){return _databases.makeDatabaseFolder}}),Object.defineProperty(exports,"makeDirectory",{enumerable:!0,get:function(){return _makeDirectory.makeDirectory}}),Object.defineProperty(exports,"readDatabaseList",{enumerable:!0,get:function(){return _databases.readDatabaseList}}),Object.defineProperty(exports,"readJson",{enumerable:!0,get:function(){return _readJson.readJson}}),Object.defineProperty(exports,"readText",{enumerable:!0,get:function(){return _readJson.readText}}),Object.defineProperty(exports,"removeDatabaseFolder",{enumerable:!0,get:function(){return _databases.removeDatabaseFolder}}),Object.defineProperty(exports,"removeDirectory",{enumerable:!0,get:function(){return _removeDirectory.removeDirectory}}),Object.defineProperty(exports,"removeFile",{enumerable:!0,get:function(){return _removeFile.removeFile}}),Object.defineProperty(exports,"storagePath",{enumerable:!0,get:function(){return _storagePath.storagePath}}),Object.defineProperty(exports,"withReadCache",{enumerable:!0,get:function(){return _readCache.withReadCache}}),Object.defineProperty(exports,"withWriteSet",{enumerable:!0,get:function(){return _writeSet.withWriteSet}}),Object.defineProperty(exports,"writeDatabaseList",{enumerable:!0,get:function(){return _databases.writeDatabaseList}}),Object.defineProperty(exports,"writeJson",{enumerable:!0,get:function(){return _writeJson.writeJson}});var _storagePath=require("./storagePath"),_readJson=require("./readJson"),_writeJson=require("./writeJson"),_makeDirectory=require("./makeDirectory"),_removeFile=require("./removeFile"),_removeDirectory=require("./removeDirectory"),_fileExists=require("./fileExists"),_listFiles=require("./listFiles"),_databases=require("./databases"),_readCache=require("./readCache"),_writeSet=require("./writeSet");
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every file in a folder of the database and the folders inside it, as paths inside the database (such as
|
|
3
|
+
* `users/1.json`), sorted. During a statement it counts what the statement has written or deleted (see withWriteSet).
|
|
4
|
+
* A folder that doesn't exist has no files. Node only.
|
|
5
|
+
* @param path - A path inside the database, such as `users`. Empty for the whole database.
|
|
6
|
+
*/
|
|
7
|
+
export declare const listFiles: (path?: string) => Promise<string[]>;
|
|
8
|
+
//# sourceMappingURL=listFiles.d.ts.map
|