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
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type packResult = {
|
|
2
|
+
records: number;
|
|
3
|
+
rows: number;
|
|
4
|
+
};
|
|
5
|
+
export type packCheck = {
|
|
6
|
+
stale: string[];
|
|
7
|
+
orphaned: string[];
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Write every record of the configured database into one packed file (`__packed/<record>.json`, compact JSON): its
|
|
11
|
+
* rows in the record's order. A browser then reads a record in one request instead of one per row when it needs more
|
|
12
|
+
* rows than one round of requests (see packedReads in configure); a static site runs this as a build step, after its data changes. The entry files
|
|
13
|
+
* stay the copy that's edited and reviewed; any insert, update or delete through json-fs-query removes the record's
|
|
14
|
+
* packed file, and reads only use one that matches its record, so a packed file is never read in place of a change
|
|
15
|
+
* made through json-fs-query. Packed files of records that no longer exist are removed.
|
|
16
|
+
*
|
|
17
|
+
* Runs as one statement (the public version, see withWriteSet): a row that can't be read fails it and nothing is
|
|
18
|
+
* written. Node only.
|
|
19
|
+
*/
|
|
20
|
+
export declare const packDatabase: () => Promise<packResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Which records' packed files don't match their entry files (missing, or packed before a change made by
|
|
23
|
+
* hand), and which packed files belong to no record, without changing anything: for a build or test to check that
|
|
24
|
+
* packDatabase has run since the data last changed. Node only.
|
|
25
|
+
*/
|
|
26
|
+
export declare const checkPacked: () => Promise<packCheck>;
|
|
27
|
+
//# sourceMappingURL=packDatabase.d.ts.map
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.packDatabase = exports.checkPacked = 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
|
+
require("core-js/modules/esnext.iterator.map.js");
|
|
11
|
+
require("core-js/modules/esnext.set.add-all.js");
|
|
12
|
+
require("core-js/modules/esnext.set.delete-all.js");
|
|
13
|
+
require("core-js/modules/esnext.set.difference.js");
|
|
14
|
+
require("core-js/modules/esnext.set.every.js");
|
|
15
|
+
require("core-js/modules/esnext.set.filter.js");
|
|
16
|
+
require("core-js/modules/esnext.set.find.js");
|
|
17
|
+
require("core-js/modules/esnext.set.intersection.js");
|
|
18
|
+
require("core-js/modules/esnext.set.is-disjoint-from.js");
|
|
19
|
+
require("core-js/modules/esnext.set.is-subset-of.js");
|
|
20
|
+
require("core-js/modules/esnext.set.is-superset-of.js");
|
|
21
|
+
require("core-js/modules/esnext.set.join.js");
|
|
22
|
+
require("core-js/modules/esnext.set.map.js");
|
|
23
|
+
require("core-js/modules/esnext.set.reduce.js");
|
|
24
|
+
require("core-js/modules/esnext.set.some.js");
|
|
25
|
+
require("core-js/modules/esnext.set.symmetric-difference.js");
|
|
26
|
+
require("core-js/modules/esnext.set.union.js");
|
|
27
|
+
var _storage = require("../storage");
|
|
28
|
+
var _retrieveRecord = require("../utilities/retrieveRecord");
|
|
29
|
+
var _retrieveFiles = require("../utilities/retrieveFiles");
|
|
30
|
+
var _retrieveRecords = require("../utilities/retrieveRecords");
|
|
31
|
+
var _packedTable = require("../utilities/packedTable");
|
|
32
|
+
var _showRecords = require("../queries/showRecords");
|
|
33
|
+
var _requireNode = require("../utilities/requireNode");
|
|
34
|
+
/**
|
|
35
|
+
* The packed file a record should have, read from its entry files (never from a packed file), as the compact
|
|
36
|
+
* text packDatabase writes.
|
|
37
|
+
* @param name - The record's name.
|
|
38
|
+
*/
|
|
39
|
+
const packedText = async name => {
|
|
40
|
+
const record = await (0, _retrieveRecord.retrieveRecord)(name);
|
|
41
|
+
const entries = record.entries || [];
|
|
42
|
+
const rows = await (0, _retrieveFiles.retrieveFiles)(entries.map(file => `${record.path}/${file}`), _retrieveRecords.retrieveEntry);
|
|
43
|
+
const packed = {
|
|
44
|
+
entries,
|
|
45
|
+
rows
|
|
46
|
+
};
|
|
47
|
+
return {
|
|
48
|
+
path: (0, _packedTable.packedPath)(record.path),
|
|
49
|
+
text: (0, _storage.jsonText)(packed, 'compact'),
|
|
50
|
+
rows: entries.length
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* The packed files under `__packed/` that belong to no record (left by a record dropped outside json-fs-query, or
|
|
55
|
+
* renamed by hand).
|
|
56
|
+
* @param names - The records' names.
|
|
57
|
+
*/
|
|
58
|
+
const orphanedPacks = async names => {
|
|
59
|
+
const expected = new Set(names.map(name => (0, _packedTable.packedPath)(name)));
|
|
60
|
+
return (await (0, _storage.listFiles)('__packed')).filter(path => !expected.has(path));
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Write every record of the configured database into one packed file (`__packed/<record>.json`, compact JSON): its
|
|
64
|
+
* rows in the record's order. A browser then reads a record in one request instead of one per row when it needs more
|
|
65
|
+
* rows than one round of requests (see packedReads in configure); a static site runs this as a build step, after its data changes. The entry files
|
|
66
|
+
* stay the copy that's edited and reviewed; any insert, update or delete through json-fs-query removes the record's
|
|
67
|
+
* packed file, and reads only use one that matches its record, so a packed file is never read in place of a change
|
|
68
|
+
* made through json-fs-query. Packed files of records that no longer exist are removed.
|
|
69
|
+
*
|
|
70
|
+
* Runs as one statement (the public version, see withWriteSet): a row that can't be read fails it and nothing is
|
|
71
|
+
* written. Node only.
|
|
72
|
+
*/
|
|
73
|
+
const packDatabase = async () => {
|
|
74
|
+
(0, _requireNode.requireNode)('packDatabase');
|
|
75
|
+
const names = await (0, _showRecords.showRecords)();
|
|
76
|
+
let rows = 0;
|
|
77
|
+
for (const name of names) {
|
|
78
|
+
const packed = await packedText(name);
|
|
79
|
+
await (0, _storage.makeDirectory)(packed.path.slice(0, packed.path.lastIndexOf('/')));
|
|
80
|
+
await (0, _storage.writeJson)(packed.path, JSON.parse(packed.text), 'compact');
|
|
81
|
+
rows += packed.rows;
|
|
82
|
+
}
|
|
83
|
+
for (const path of await orphanedPacks(names)) {
|
|
84
|
+
await (0, _storage.removeFile)(path);
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
records: names.length,
|
|
88
|
+
rows
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Which records' packed files don't match their entry files (missing, or packed before a change made by
|
|
93
|
+
* hand), and which packed files belong to no record, without changing anything: for a build or test to check that
|
|
94
|
+
* packDatabase has run since the data last changed. Node only.
|
|
95
|
+
*/
|
|
96
|
+
exports.packDatabase = packDatabase;
|
|
97
|
+
const checkPacked = async () => {
|
|
98
|
+
(0, _requireNode.requireNode)('checkPacked');
|
|
99
|
+
const names = await (0, _showRecords.showRecords)();
|
|
100
|
+
const stale = [];
|
|
101
|
+
for (const name of names) {
|
|
102
|
+
const packed = await packedText(name);
|
|
103
|
+
const current = (0, _storage.fileExists)(packed.path) ? await (0, _storage.readText)(packed.path).catch(() => undefined) : undefined;
|
|
104
|
+
if (typeof current === 'undefined' || JSON.stringify(JSON.parse(current)) !== packed.text) {
|
|
105
|
+
stale.push(name);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
stale,
|
|
110
|
+
orphaned: await orphanedPacks(names)
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
exports.checkPacked = checkPacked;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.packDatabase=exports.checkPacked=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"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.set.add-all.js"),require("core-js/modules/esnext.set.delete-all.js"),require("core-js/modules/esnext.set.difference.js"),require("core-js/modules/esnext.set.every.js"),require("core-js/modules/esnext.set.filter.js"),require("core-js/modules/esnext.set.find.js"),require("core-js/modules/esnext.set.intersection.js"),require("core-js/modules/esnext.set.is-disjoint-from.js"),require("core-js/modules/esnext.set.is-subset-of.js"),require("core-js/modules/esnext.set.is-superset-of.js"),require("core-js/modules/esnext.set.join.js"),require("core-js/modules/esnext.set.map.js"),require("core-js/modules/esnext.set.reduce.js"),require("core-js/modules/esnext.set.some.js"),require("core-js/modules/esnext.set.symmetric-difference.js"),require("core-js/modules/esnext.set.union.js");var _storage=require("../storage"),_retrieveRecord=require("../utilities/retrieveRecord"),_retrieveFiles=require("../utilities/retrieveFiles"),_retrieveRecords=require("../utilities/retrieveRecords"),_packedTable=require("../utilities/packedTable"),_showRecords=require("../queries/showRecords"),_requireNode=require("../utilities/requireNode");const packedText=async e=>{const s=await(0,_retrieveRecord.retrieveRecord)(e),r=s.entries||[],t=await(0,_retrieveFiles.retrieveFiles)(r.map((e=>`${s.path}/${e}`)),_retrieveRecords.retrieveEntry),o={entries:r,rows:t};return{path:(0,_packedTable.packedPath)(s.path),text:(0,_storage.jsonText)(o,"compact"),rows:r.length}},orphanedPacks=async e=>{const s=new Set(e.map((e=>(0,_packedTable.packedPath)(e))));return(await(0,_storage.listFiles)("__packed")).filter((e=>!s.has(e)))},packDatabase=async()=>{(0,_requireNode.requireNode)("packDatabase");const e=await(0,_showRecords.showRecords)();let s=0;for(const r of e){const e=await packedText(r);await(0,_storage.makeDirectory)(e.path.slice(0,e.path.lastIndexOf("/"))),await(0,_storage.writeJson)(e.path,JSON.parse(e.text),"compact"),s+=e.rows}for(const s of await orphanedPacks(e))await(0,_storage.removeFile)(s);return{records:e.length,rows:s}};exports.packDatabase=packDatabase;const checkPacked=async()=>{(0,_requireNode.requireNode)("checkPacked");const e=await(0,_showRecords.showRecords)(),s=[];for(const r of e){const e=await packedText(r),t=(0,_storage.fileExists)(e.path)?await(0,_storage.readText)(e.path).catch((()=>{})):void 0;void 0!==t&&JSON.stringify(JSON.parse(t))===e.text||s.push(r)}return{stale:s,orphaned:await orphanedPacks(e)}};exports.checkPacked=checkPacked;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Check whether any record in the referenced entity has the given property set to the given
|
|
3
3
|
* value - the mirror image of keyUnique(), which checks that no record already has a value.
|
|
4
|
+
* A referenced field with an index (a foreign key usually references a primary key) is answered from it; otherwise
|
|
5
|
+
* every row is read.
|
|
4
6
|
* @param entity
|
|
5
7
|
* @param property
|
|
6
8
|
* @param value
|
|
@@ -8,22 +8,28 @@ var _retrieveRecords = require("../../utilities/retrieveRecords");
|
|
|
8
8
|
var _where = require("../../queries/where");
|
|
9
9
|
var _retrieveRecord = require("../../utilities/retrieveRecord");
|
|
10
10
|
var _fieldType = require("../../utilities/fieldType");
|
|
11
|
+
var _indexHas = require("../../utilities/indexHas");
|
|
11
12
|
/**
|
|
12
13
|
* Check whether any record in the referenced entity has the given property set to the given
|
|
13
14
|
* value - the mirror image of keyUnique(), which checks that no record already has a value.
|
|
15
|
+
* A referenced field with an index (a foreign key usually references a primary key) is answered from it; otherwise
|
|
16
|
+
* every row is read.
|
|
14
17
|
* @param entity
|
|
15
18
|
* @param property
|
|
16
19
|
* @param value
|
|
17
20
|
*/
|
|
18
21
|
const foreignKeyExists = async (entity, property, value) => {
|
|
22
|
+
const found = await (0, _indexHas.indexHas)(entity, property, value);
|
|
23
|
+
if (typeof found !== 'undefined') {
|
|
24
|
+
return found;
|
|
25
|
+
}
|
|
19
26
|
const records = await (0, _retrieveRecords.retrieveRecords)(entity);
|
|
20
27
|
const type = (0, _fieldType.fieldType)(await (0, _retrieveRecord.retrieveRecord)(entity), property);
|
|
21
|
-
|
|
28
|
+
return (0, _where.where)(records, {
|
|
22
29
|
property,
|
|
23
30
|
comparator: '=',
|
|
24
31
|
value,
|
|
25
32
|
type
|
|
26
|
-
});
|
|
27
|
-
return found.length > 0;
|
|
33
|
+
}).length > 0;
|
|
28
34
|
};
|
|
29
35
|
exports.foreignKeyExists = foreignKeyExists;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.foreignKeyExists=void 0;var _retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where"),_retrieveRecord=require("../../utilities/retrieveRecord"),_fieldType=require("../../utilities/fieldType");const foreignKeyExists=async(e,r,i)=>{const t=await(0,_retrieveRecords.retrieveRecords)(e),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.foreignKeyExists=void 0;var _retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where"),_retrieveRecord=require("../../utilities/retrieveRecord"),_fieldType=require("../../utilities/fieldType"),_indexHas=require("../../utilities/indexHas");const foreignKeyExists=async(e,r,i)=>{const t=await(0,_indexHas.indexHas)(e,r,i);if(void 0!==t)return t;const s=await(0,_retrieveRecords.retrieveRecords)(e),o=(0,_fieldType.fieldType)(await(0,_retrieveRecord.retrieveRecord)(e),r);return(0,_where.where)(s,{property:r,comparator:"=",value:i,type:o}).length>0};exports.foreignKeyExists=foreignKeyExists;
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Check whether any other record, in any entity, still has a single-field foreign key pointing
|
|
3
3
|
* at entity.property = value - the mirror image of foreignKeyExists(), which checks the opposite
|
|
4
4
|
* direction (that a new/updated foreign key value points at something real). Used to RESTRICT a
|
|
5
|
-
* delete or update that would otherwise leave a dangling reference behind.
|
|
6
|
-
* the database via the __RECORDS registry
|
|
7
|
-
*
|
|
5
|
+
* delete or update that would otherwise leave a dangling reference behind. Looks at every record in
|
|
6
|
+
* the database (via the __RECORDS registry) for a foreign key to entity.property. A foreign key field with an index
|
|
7
|
+
* (each one gets one) is answered from it; otherwise that record's rows are read.
|
|
8
8
|
* @param entity
|
|
9
9
|
* @param property
|
|
10
10
|
* @param value
|
|
@@ -10,13 +10,14 @@ var _retrieveRecords = require("../../utilities/retrieveRecords");
|
|
|
10
10
|
var _where = require("../../queries/where");
|
|
11
11
|
var _fieldType = require("../../utilities/fieldType");
|
|
12
12
|
var _splitEntityProperty = require("../../utilities/parsers/splitEntityProperty");
|
|
13
|
+
var _indexHas = require("../../utilities/indexHas");
|
|
13
14
|
/**
|
|
14
15
|
* Check whether any other record, in any entity, still has a single-field foreign key pointing
|
|
15
16
|
* at entity.property = value - the mirror image of foreignKeyExists(), which checks the opposite
|
|
16
17
|
* direction (that a new/updated foreign key value points at something real). Used to RESTRICT a
|
|
17
|
-
* delete or update that would otherwise leave a dangling reference behind.
|
|
18
|
-
* the database via the __RECORDS registry
|
|
19
|
-
*
|
|
18
|
+
* delete or update that would otherwise leave a dangling reference behind. Looks at every record in
|
|
19
|
+
* the database (via the __RECORDS registry) for a foreign key to entity.property. A foreign key field with an index
|
|
20
|
+
* (each one gets one) is answered from it; otherwise that record's rows are read.
|
|
20
21
|
* @param entity
|
|
21
22
|
* @param property
|
|
22
23
|
* @param value
|
|
@@ -37,6 +38,13 @@ const hasDependents = async (entity, property, value) => {
|
|
|
37
38
|
if (refEntity !== entity || refProperty !== property) {
|
|
38
39
|
continue;
|
|
39
40
|
}
|
|
41
|
+
const indexed = await (0, _indexHas.indexHas)(otherEntity, key.fields[0], value);
|
|
42
|
+
if (typeof indexed !== 'undefined') {
|
|
43
|
+
if (indexed) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
40
48
|
const records = await (0, _retrieveRecords.retrieveRecords)(otherEntity);
|
|
41
49
|
const found = (0, _where.where)(records, {
|
|
42
50
|
property: key.fields[0],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.hasDependents=void 0;var _describe=require("../describe"),_retrieveRecord=require("../../utilities/retrieveRecord"),_retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where"),_fieldType=require("../../utilities/fieldType"),_splitEntityProperty=require("../../utilities/parsers/splitEntityProperty");const hasDependents=async(e,r,
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.hasDependents=void 0;var _describe=require("../describe"),_retrieveRecord=require("../../utilities/retrieveRecord"),_retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where"),_fieldType=require("../../utilities/fieldType"),_splitEntityProperty=require("../../utilities/parsers/splitEntityProperty"),_indexHas=require("../../utilities/indexHas");const hasDependents=async(e,r,i)=>{const t=await(0,_describe.describe)();for(const s of t){const t=s.replace(/\.json$/,""),n=await(0,_retrieveRecord.retrieveRecord)(t);for(const s of n.keys){if("foreign"!==s.type||1!==s.fields.length||!s.references||1!==s.references.length)continue;const{entity:o,property:d}=(0,_splitEntityProperty.splitEntityProperty)(s.references[0].fields[0]);if(o!==e||d!==r)continue;const c=await(0,_indexHas.indexHas)(t,s.fields[0],i);if(void 0!==c){if(c)return!0;continue}const p=await(0,_retrieveRecords.retrieveRecords)(t);if((0,_where.where)(p,{property:s.fields[0],comparator:"=",value:i,type:(0,_fieldType.fieldType)(n,s.fields[0])}).length)return!0}}return!1};exports.hasDependents=hasDependents;
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
* Check that no existing record already has this combination of values across all of the given
|
|
3
3
|
* fields - a single field for a normal unique/primary key, or several for a composite one.
|
|
4
4
|
* references and checkKeys are parallel arrays: references[i]'s value must equal checkKeys[i].
|
|
5
|
+
*
|
|
6
|
+
* One field with an index (every primary and unique key has one) is answered from the index; a composite key, or a
|
|
7
|
+
* field without one, reads every row.
|
|
5
8
|
* @param entity
|
|
6
9
|
* @param references
|
|
7
10
|
* @param checkKeys
|
|
@@ -8,10 +8,14 @@ var _retrieveRecords = require("../../utilities/retrieveRecords");
|
|
|
8
8
|
var _where = require("../../queries/where");
|
|
9
9
|
var _retrieveRecord = require("../../utilities/retrieveRecord");
|
|
10
10
|
var _fieldType = require("../../utilities/fieldType");
|
|
11
|
+
var _indexHas = require("../../utilities/indexHas");
|
|
11
12
|
/**
|
|
12
13
|
* Check that no existing record already has this combination of values across all of the given
|
|
13
14
|
* fields - a single field for a normal unique/primary key, or several for a composite one.
|
|
14
15
|
* references and checkKeys are parallel arrays: references[i]'s value must equal checkKeys[i].
|
|
16
|
+
*
|
|
17
|
+
* One field with an index (every primary and unique key has one) is answered from the index; a composite key, or a
|
|
18
|
+
* field without one, reads every row.
|
|
15
19
|
* @param entity
|
|
16
20
|
* @param references
|
|
17
21
|
* @param checkKeys
|
|
@@ -20,6 +24,12 @@ const keyUnique = async (entity, references = [], checkKeys = []) => {
|
|
|
20
24
|
if (!references.length || references.length !== checkKeys.length) {
|
|
21
25
|
return false;
|
|
22
26
|
}
|
|
27
|
+
if (references.length === 1) {
|
|
28
|
+
const found = await (0, _indexHas.indexHas)(entity, references[0], checkKeys[0]);
|
|
29
|
+
if (typeof found !== 'undefined') {
|
|
30
|
+
return !found;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
23
33
|
let records = await (0, _retrieveRecords.retrieveRecords)(entity);
|
|
24
34
|
const record = await (0, _retrieveRecord.retrieveRecord)(entity);
|
|
25
35
|
for (let i = 0; i < references.length; i++) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.keyUnique=void 0;var _retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where"),_retrieveRecord=require("../../utilities/retrieveRecord"),_fieldType=require("../../utilities/fieldType");const keyUnique=async(e,r=[],
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.keyUnique=void 0;var _retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where"),_retrieveRecord=require("../../utilities/retrieveRecord"),_fieldType=require("../../utilities/fieldType"),_indexHas=require("../../utilities/indexHas");const keyUnique=async(e,r=[],i=[])=>{if(!r.length||r.length!==i.length)return!1;if(1===r.length){const t=await(0,_indexHas.indexHas)(e,r[0],i[0]);if(void 0!==t)return!t}let t=await(0,_retrieveRecords.retrieveRecords)(e);const s=await(0,_retrieveRecord.retrieveRecord)(e);for(let e=0;e<r.length;e++)t=(0,_where.where)(t,{property:r[e],comparator:"=",value:i[e],type:(0,_fieldType.fieldType)(s,r[e])});return!t.length};exports.keyUnique=keyUnique;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `create database [if not exists] <name>`: a new, empty database in the folder holding them (databasesPath). It
|
|
3
|
+
* doesn't switch to it (see use). The name is listed before the folder is made, so a stop part way leaves a listed
|
|
4
|
+
* database whose folder appears with its first record, never a folder no list names. A folder that's there but not
|
|
5
|
+
* listed (copied in by hand, or left by an older version) is listed by `if not exists`. Node only.
|
|
6
|
+
* @param name
|
|
7
|
+
* @param ifNotExists
|
|
8
|
+
* @returns The name, or null when it existed and `if not exists` was given.
|
|
9
|
+
*/
|
|
10
|
+
export declare const createDatabase: (name: string, ifNotExists?: boolean) => Promise<string | null>;
|
|
11
|
+
/**
|
|
12
|
+
* `drop database [if exists] <name>`: delete a database, its records and every row in them. The database in use can't
|
|
13
|
+
* be dropped (use another one first). Node only.
|
|
14
|
+
* @param name
|
|
15
|
+
* @param ifExists
|
|
16
|
+
* @returns The name, or null when it didn't exist and `if exists` was given.
|
|
17
|
+
*/
|
|
18
|
+
export declare const dropDatabase: (name: string, ifExists?: boolean) => Promise<string | null>;
|
|
19
|
+
/**
|
|
20
|
+
* `use <name>`: switch to another database in the folder holding them, for the rest of the call and the calls after it
|
|
21
|
+
* (as configure({ database }) does). Works in a browser too (reading only), for a database listed in
|
|
22
|
+
* `__DATABASES.json`, while no other call is running in the page.
|
|
23
|
+
* @param name
|
|
24
|
+
* @returns The name.
|
|
25
|
+
*/
|
|
26
|
+
export declare const useDatabase: (name: string) => Promise<string>;
|
|
27
|
+
/**
|
|
28
|
+
* `show databases`: the databases' names, in the order they were created.
|
|
29
|
+
*/
|
|
30
|
+
export declare const showDatabases: () => Promise<string[]>;
|
|
31
|
+
//# sourceMappingURL=databaseStatements.d.ts.map
|
|
@@ -0,0 +1,97 @@
|
|
|
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.useDatabase = exports.showDatabases = exports.dropDatabase = exports.createDatabase = void 0;
|
|
8
|
+
require("core-js/modules/es.array.includes.js");
|
|
9
|
+
require("core-js/modules/esnext.iterator.constructor.js");
|
|
10
|
+
require("core-js/modules/esnext.iterator.filter.js");
|
|
11
|
+
var jsEnv = _interopRequireWildcard(require("browser-or-node"));
|
|
12
|
+
var _config = require("../utilities/config");
|
|
13
|
+
var _requireNode = require("../utilities/requireNode");
|
|
14
|
+
var _databaseLock = require("../utilities/databaseLock");
|
|
15
|
+
var _storage = require("../storage");
|
|
16
|
+
var e;
|
|
17
|
+
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; }
|
|
18
|
+
/**
|
|
19
|
+
* Whether a database exists: listed in `__DATABASES.json`, or (in Node) a folder of that name is there.
|
|
20
|
+
* @param name
|
|
21
|
+
*/
|
|
22
|
+
const databaseExists = async name => (await (0, _storage.readDatabaseList)()).includes(name) || jsEnv.isNode && (0, _storage.databaseFolderExists)(name);
|
|
23
|
+
/**
|
|
24
|
+
* `create database [if not exists] <name>`: a new, empty database in the folder holding them (databasesPath). It
|
|
25
|
+
* doesn't switch to it (see use). The name is listed before the folder is made, so a stop part way leaves a listed
|
|
26
|
+
* database whose folder appears with its first record, never a folder no list names. A folder that's there but not
|
|
27
|
+
* listed (copied in by hand, or left by an older version) is listed by `if not exists`. Node only.
|
|
28
|
+
* @param name
|
|
29
|
+
* @param ifNotExists
|
|
30
|
+
* @returns The name, or null when it existed and `if not exists` was given.
|
|
31
|
+
*/
|
|
32
|
+
const createDatabase = async (name, ifNotExists = false) => {
|
|
33
|
+
(0, _requireNode.requireNode)('"create database"');
|
|
34
|
+
const listed = await (0, _storage.readDatabaseList)();
|
|
35
|
+
if (listed.includes(name) || (0, _storage.databaseFolderExists)(name)) {
|
|
36
|
+
if (!ifNotExists) {
|
|
37
|
+
throw new Error(listed.includes(name) ? `Database "${name}" already exists` : `Database "${name}" already exists as a folder that isn't listed: create database if not exists ${name} lists it`);
|
|
38
|
+
}
|
|
39
|
+
if (!listed.includes(name)) {
|
|
40
|
+
await (0, _storage.writeDatabaseList)([...listed, name]);
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
await (0, _storage.writeDatabaseList)([...listed, name]);
|
|
45
|
+
await (0, _storage.makeDatabaseFolder)(name);
|
|
46
|
+
return name;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* `drop database [if exists] <name>`: delete a database, its records and every row in them. The database in use can't
|
|
50
|
+
* be dropped (use another one first). Node only.
|
|
51
|
+
* @param name
|
|
52
|
+
* @param ifExists
|
|
53
|
+
* @returns The name, or null when it didn't exist and `if exists` was given.
|
|
54
|
+
*/
|
|
55
|
+
exports.createDatabase = createDatabase;
|
|
56
|
+
const dropDatabase = async (name, ifExists = false) => {
|
|
57
|
+
(0, _requireNode.requireNode)('"drop database"');
|
|
58
|
+
if (!(await databaseExists(name))) {
|
|
59
|
+
if (ifExists) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
throw new Error(`Database "${name}" doesn't exist`);
|
|
63
|
+
}
|
|
64
|
+
if ((0, _config.getSetting)('database', undefined) === name) {
|
|
65
|
+
throw new Error(`Can't drop the database in use ("${name}"): use another one first`);
|
|
66
|
+
}
|
|
67
|
+
// Unlisted first: a stop part way leaves a folder no list names, never a listed database with no folder
|
|
68
|
+
await (0, _storage.writeDatabaseList)((await (0, _storage.readDatabaseList)()).filter(listed => listed !== name));
|
|
69
|
+
await (0, _storage.removeDatabaseFolder)(name);
|
|
70
|
+
return name;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* `use <name>`: switch to another database in the folder holding them, for the rest of the call and the calls after it
|
|
74
|
+
* (as configure({ database }) does). Works in a browser too (reading only), for a database listed in
|
|
75
|
+
* `__DATABASES.json`, while no other call is running in the page.
|
|
76
|
+
* @param name
|
|
77
|
+
* @returns The name.
|
|
78
|
+
*/
|
|
79
|
+
exports.dropDatabase = dropDatabase;
|
|
80
|
+
const useDatabase = async name => {
|
|
81
|
+
// A browser runs calls side by side (see withDatabaseLock), and there's one database in use for the page: switching
|
|
82
|
+
// now would move the other calls to it part way
|
|
83
|
+
if (!jsEnv.isNode && (0, _databaseLock.browserCallsRunning)() > 1) {
|
|
84
|
+
throw new Error(`Can't use "${name}" while other calls are running in this page: await them first, or pick the database with configure({ database }) between calls`);
|
|
85
|
+
}
|
|
86
|
+
if (!(await databaseExists(name))) {
|
|
87
|
+
throw new Error(`Database "${name}" doesn't exist${jsEnv.isNode ? '' : ' (or isn\'t listed in __DATABASES.json)'}`);
|
|
88
|
+
}
|
|
89
|
+
(0, _config.switchDatabase)(name);
|
|
90
|
+
return name;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* `show databases`: the databases' names, in the order they were created.
|
|
94
|
+
*/
|
|
95
|
+
exports.useDatabase = useDatabase;
|
|
96
|
+
const showDatabases = async () => (0, _storage.readDatabaseList)();
|
|
97
|
+
exports.showDatabases = showDatabases;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";require("core-js/modules/esnext.weak-map.delete-all.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.useDatabase=exports.showDatabases=exports.dropDatabase=exports.createDatabase=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");var e,jsEnv=_interopRequireWildcard(require("browser-or-node")),_config=require("../utilities/config"),_requireNode=require("../utilities/requireNode"),_databaseLock=require("../utilities/databaseLock"),_storage=require("../storage");function _interopRequireWildcard(a,t){if(!t&&a&&a.__esModule)return a;var s,r,i=Object.defineProperty,o={__proto__:null,default:a};if(Object(a)!==a)return o;if(e||"function"!=typeof WeakMap||(e=new WeakMap),e){if(e.has(a))return e.get(a);e.set(a,o)}for(r in a)"default"!==r&&{}.hasOwnProperty.call(a,r)&&((s=i&&Object.getOwnPropertyDescriptor(a,r))&&(s.get||s.set)?i(o,r,s):o[r]=a[r]);return o}const databaseExists=async e=>(await(0,_storage.readDatabaseList)()).includes(e)||jsEnv.isNode&&(0,_storage.databaseFolderExists)(e),createDatabase=async(e,a=!1)=>{(0,_requireNode.requireNode)('"create database"');const t=await(0,_storage.readDatabaseList)();if(t.includes(e)||(0,_storage.databaseFolderExists)(e)){if(!a)throw new Error(t.includes(e)?`Database "${e}" already exists`:`Database "${e}" already exists as a folder that isn't listed: create database if not exists ${e} lists it`);return t.includes(e)||await(0,_storage.writeDatabaseList)([...t,e]),null}return await(0,_storage.writeDatabaseList)([...t,e]),await(0,_storage.makeDatabaseFolder)(e),e};exports.createDatabase=createDatabase;const dropDatabase=async(e,a=!1)=>{if((0,_requireNode.requireNode)('"drop database"'),!await databaseExists(e)){if(a)return null;throw new Error(`Database "${e}" doesn't exist`)}if((0,_config.getSetting)("database",void 0)===e)throw new Error(`Can't drop the database in use ("${e}"): use another one first`);return await(0,_storage.writeDatabaseList)((await(0,_storage.readDatabaseList)()).filter((a=>a!==e))),await(0,_storage.removeDatabaseFolder)(e),e};exports.dropDatabase=dropDatabase;const useDatabase=async e=>{if(!jsEnv.isNode&&(0,_databaseLock.browserCallsRunning)()>1)throw new Error(`Can't use "${e}" while other calls are running in this page: await them first, or pick the database with configure({ database }) between calls`);if(!await databaseExists(e))throw new Error(`Database "${e}" doesn't exist${jsEnv.isNode?"":" (or isn't listed in __DATABASES.json)"}`);return(0,_config.switchDatabase)(e),e};exports.useDatabase=useDatabase;const showDatabases=async()=>(0,_storage.readDatabaseList)();exports.showDatabases=showDatabases;
|
|
@@ -4,8 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.deleteEntity = void 0;
|
|
7
|
-
require("core-js/modules/es.json.stringify.js");
|
|
8
7
|
require("core-js/modules/esnext.iterator.constructor.js");
|
|
8
|
+
require("core-js/modules/esnext.iterator.filter.js");
|
|
9
9
|
require("core-js/modules/esnext.iterator.find.js");
|
|
10
10
|
require("core-js/modules/esnext.iterator.map.js");
|
|
11
11
|
require("core-js/modules/esnext.set.add-all.js");
|
|
@@ -31,10 +31,9 @@ var _computeKeyValue = require("../utilities/computeKeyValue");
|
|
|
31
31
|
var _fieldType = require("../utilities/fieldType");
|
|
32
32
|
var _hasDependents = require("../introspect/policies/hasDependents");
|
|
33
33
|
var _config = require("../utilities/config");
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
} = require('fs/promises');
|
|
34
|
+
var _keyIndexFiles = require("../utilities/keyIndexFiles");
|
|
35
|
+
var _storage = require("../storage");
|
|
36
|
+
var _packedTable = require("../utilities/packedTable");
|
|
38
37
|
/**
|
|
39
38
|
* RESTRICT: reject the whole delete (before removing anything) if any row being deleted is still
|
|
40
39
|
* referenced by a single-field foreign key elsewhere. Only meaningful for a single-field primary
|
|
@@ -57,32 +56,45 @@ const assertNoDependents = async (entity, primaryKey, toDelete) => {
|
|
|
57
56
|
};
|
|
58
57
|
/**
|
|
59
58
|
* A record object carries no memory of which entry file it was read from, and files are not
|
|
60
|
-
* guaranteed to be named after any field's value, so
|
|
61
|
-
*
|
|
62
|
-
*
|
|
59
|
+
* guaranteed to be named after any field's value, so a deleted row's file is found by its primary
|
|
60
|
+
* key value(s) - a single field, or a composite of several for a multi-field primary key. The
|
|
61
|
+
* primary key's index says which files those are (each is read to confirm it); any deleted value
|
|
62
|
+
* the index didn't lead to, or a record without one, is found by looking at every entry, as before.
|
|
63
|
+
* Inserts and updates keep primary key values unique, so each value is one row: only a database
|
|
64
|
+
* edited by hand into two rows of one value, with an index listing just one, would keep the other
|
|
65
|
+
* (looking at every entry used to delete both).
|
|
63
66
|
* @param entity
|
|
64
67
|
* @param record
|
|
65
68
|
* @param primaryKey
|
|
66
69
|
* @param deletedValues
|
|
67
70
|
*/
|
|
68
71
|
const removeMatchingEntries = async (entity, record, primaryKey, deletedValues) => {
|
|
69
|
-
const
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
+
const removed = new Set();
|
|
73
|
+
const found = new Set();
|
|
74
|
+
const removeIfDeleted = async fileName => {
|
|
72
75
|
const data = await (0, _retrieveFile.retrieveFile)(`${record.path}/${fileName}`);
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
const value = (0, _computeKeyValue.computeKeyValue)(primaryKey.fields, data);
|
|
77
|
+
if (!deletedValues.has(value)) {
|
|
78
|
+
return;
|
|
76
79
|
}
|
|
77
|
-
await
|
|
80
|
+
await (0, _storage.removeFile)(`${record.path}/${fileName}`);
|
|
78
81
|
for (const key of record.keys) {
|
|
79
82
|
await (0, _removeFromIndex.removeFromIndex)(record.path, key, (0, _computeKeyValue.computeKeyValue)(key.fields, data), fileName, (0, _fieldType.keyValueType)(record, key));
|
|
80
83
|
}
|
|
84
|
+
removed.add(fileName);
|
|
85
|
+
found.add(value);
|
|
86
|
+
};
|
|
87
|
+
for (const fileName of (await (0, _keyIndexFiles.keyIndexFiles)(record, primaryKey, value => deletedValues.has(value))) ?? []) {
|
|
88
|
+
await removeIfDeleted(fileName);
|
|
81
89
|
}
|
|
82
|
-
|
|
90
|
+
if (found.size < deletedValues.size) {
|
|
91
|
+
for (const fileName of record.entries.filter(entry => !removed.has(entry))) {
|
|
92
|
+
await removeIfDeleted(fileName);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return record.entries.filter(fileName => !removed.has(fileName));
|
|
83
96
|
};
|
|
84
97
|
const deleteEntity = async (entity = '', dataSet = {}) => {
|
|
85
|
-
const databasePath = (0, _config.getSetting)('databasePath', 'database/');
|
|
86
98
|
const record = await (0, _retrieveRecord.retrieveRecord)(entity);
|
|
87
99
|
const primaryKey = record.keys.find(key => key.type === 'primary');
|
|
88
100
|
if (!primaryKey) {
|
|
@@ -94,8 +106,12 @@ const deleteEntity = async (entity = '', dataSet = {}) => {
|
|
|
94
106
|
}
|
|
95
107
|
await assertNoDependents(entity, primaryKey, toDelete);
|
|
96
108
|
const deletedValues = new Set(toDelete.map(row => (0, _computeKeyValue.computeKeyValue)(primaryKey.fields, row)));
|
|
97
|
-
|
|
98
|
-
|
|
109
|
+
const remaining = await removeMatchingEntries(entity, record, primaryKey, deletedValues);
|
|
110
|
+
if (remaining.length !== record.entries.length) {
|
|
111
|
+
await (0, _packedTable.discardPacked)(record.path);
|
|
112
|
+
}
|
|
113
|
+
record.entries = remaining;
|
|
114
|
+
await (0, _storage.writeJson)(`${record.path}.json`, record);
|
|
99
115
|
return dataSet;
|
|
100
116
|
};
|
|
101
117
|
exports.deleteEntity = deleteEntity;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.deleteEntity=void 0,require("core-js/modules/
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.deleteEntity=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.filter.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.set.add-all.js"),require("core-js/modules/esnext.set.delete-all.js"),require("core-js/modules/esnext.set.difference.js"),require("core-js/modules/esnext.set.every.js"),require("core-js/modules/esnext.set.filter.js"),require("core-js/modules/esnext.set.find.js"),require("core-js/modules/esnext.set.intersection.js"),require("core-js/modules/esnext.set.is-disjoint-from.js"),require("core-js/modules/esnext.set.is-subset-of.js"),require("core-js/modules/esnext.set.is-superset-of.js"),require("core-js/modules/esnext.set.join.js"),require("core-js/modules/esnext.set.map.js"),require("core-js/modules/esnext.set.reduce.js"),require("core-js/modules/esnext.set.some.js"),require("core-js/modules/esnext.set.symmetric-difference.js"),require("core-js/modules/esnext.set.union.js");var _retrieveRecord=require("../utilities/retrieveRecord"),_retrieveFile=require("../utilities/retrieveFile"),_removeFromIndex=require("../utilities/removeFromIndex"),_computeKeyValue=require("../utilities/computeKeyValue"),_fieldType=require("../utilities/fieldType"),_hasDependents=require("../introspect/policies/hasDependents"),_config=require("../utilities/config"),_keyIndexFiles=require("../utilities/keyIndexFiles"),_storage=require("../storage"),_packedTable=require("../utilities/packedTable");const assertNoDependents=async(e,r,s)=>{if(!(0,_config.getSetting)("enforceForeignKeys",!0)||1!==r.fields.length)return;const t=r.fields[0];for(const r of s)if(await(0,_hasDependents.hasDependents)(e,t,r[t]))throw new Error(`Cannot delete from "${e}" where "${t}" = ${r[t]} - other records still reference it`)},removeMatchingEntries=async(e,r,s,t)=>{const i=new Set,o=new Set,n=async e=>{const n=await(0,_retrieveFile.retrieveFile)(`${r.path}/${e}`),u=(0,_computeKeyValue.computeKeyValue)(s.fields,n);if(t.has(u)){await(0,_storage.removeFile)(`${r.path}/${e}`);for(const s of r.keys)await(0,_removeFromIndex.removeFromIndex)(r.path,s,(0,_computeKeyValue.computeKeyValue)(s.fields,n),e,(0,_fieldType.keyValueType)(r,s));i.add(e),o.add(u)}};for(const e of await(0,_keyIndexFiles.keyIndexFiles)(r,s,(e=>t.has(e)))??[])await n(e);if(o.size<t.size)for(const e of r.entries.filter((e=>!i.has(e))))await n(e);return r.entries.filter((e=>!i.has(e)))},deleteEntity=async(e="",r={})=>{const s=await(0,_retrieveRecord.retrieveRecord)(e),t=s.keys.find((e=>"primary"===e.type));if(!t)throw new Error(`Cannot delete from "${e}" without a primary key`);const i=r[e]||[];if(!i.length)return r;await assertNoDependents(e,t,i);const o=new Set(i.map((e=>(0,_computeKeyValue.computeKeyValue)(t.fields,e)))),n=await removeMatchingEntries(0,s,t,o);return n.length!==s.entries.length&&await(0,_packedTable.discardPacked)(s.path),s.entries=n,await(0,_storage.writeJson)(`${s.path}.json`,s),r};exports.deleteEntity=deleteEntity;
|
|
@@ -1,2 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Insert rows into a record, all in one statement: every row is checked (against the rows in storage and the rows
|
|
3
|
+
* before it in the statement) and its entry file written, then the record file and each index are written once.
|
|
4
|
+
* Inside a write set (as every query runs, see withWriteSet) a row that fails leaves none of them written.
|
|
5
|
+
* @param entity
|
|
6
|
+
* @param values - The rows, as field -> value.
|
|
7
|
+
* @param dataSet
|
|
8
|
+
*/
|
|
1
9
|
export declare const insertEntity: (entity?: string, values?: Object[], dataSet?: Object) => Promise<Object>;
|
|
2
10
|
//# sourceMappingURL=insertEntity.d.ts.map
|