datafolder 1.0.16 → 1.0.17
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 +2 -0
- package/data/northwind.json +31945 -0
- package/package.json +1 -1
- package/src/QyAcl.js +1 -1
- package/src/QyFileContentUtils.d.ts +2 -2
- package/src/QyFileContentUtils.js +22 -24
- package/test/testQyNorthwind.js +206 -0
package/package.json
CHANGED
package/src/QyAcl.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare function mergeContent(oldContent: any, newContent: any): any;
|
|
2
|
-
export declare function
|
|
2
|
+
export declare function mergeChanges(oldChanges: any, newChanges: any): any;
|
|
3
3
|
export declare function mergeContentAndGenDelta(oldContent: any, newContent: any): {
|
|
4
4
|
merged: any;
|
|
5
5
|
delta: any;
|
|
@@ -7,5 +7,5 @@ export declare function mergeContentAndGenDelta(oldContent: any, newContent: any
|
|
|
7
7
|
export declare function setValByNamePath(rootObj: any, namePath: any, value: any): any;
|
|
8
8
|
export declare function getValByNamePath(obj: any, namePath: any): any;
|
|
9
9
|
export declare function delValByNamePath(obj: any, propPath: any, keepEmptyObj?: boolean, idx?: number): any;
|
|
10
|
-
export declare function cleanContent(obj: any, shouldCleanMark?: boolean
|
|
10
|
+
export declare function cleanContent(obj: any, shouldCleanMark?: boolean): any;
|
|
11
11
|
export declare function objToDelMarks(obj: any): any;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
isNotNullObj as
|
|
2
|
+
isNotNullObj as f,
|
|
3
3
|
trimArrayTail as g,
|
|
4
4
|
isSimpleType as h,
|
|
5
5
|
SpecialOperators as r,
|
|
@@ -12,7 +12,7 @@ let p = Array.isArray, {
|
|
|
12
12
|
$ext: y
|
|
13
13
|
} = r;
|
|
14
14
|
|
|
15
|
-
function
|
|
15
|
+
function a(r, n) {
|
|
16
16
|
if (null == n) return r;
|
|
17
17
|
if (n !== m) {
|
|
18
18
|
if (h(n)) return n;
|
|
@@ -22,7 +22,7 @@ function f(r, n) {
|
|
|
22
22
|
if (r != n) {
|
|
23
23
|
var l, t = p(r);
|
|
24
24
|
for (l in n) {
|
|
25
|
-
var u =
|
|
25
|
+
var u = a(r[l], n[l]);
|
|
26
26
|
null == u ? (delete r[l], t && g(r)) : r[l] = u;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
@@ -34,7 +34,7 @@ function o(r, n) {
|
|
|
34
34
|
if (n == m) return m;
|
|
35
35
|
if (null != n[w]) return n;
|
|
36
36
|
var e = r[w];
|
|
37
|
-
if (null != e) r[w] =
|
|
37
|
+
if (null != e) r[w] = a(e, n); else {
|
|
38
38
|
if (r == m) return {
|
|
39
39
|
[w]: O(n)
|
|
40
40
|
};
|
|
@@ -53,8 +53,7 @@ function n(r, n) {
|
|
|
53
53
|
newValue: {}
|
|
54
54
|
};
|
|
55
55
|
r = S(r, n, [], 0, e);
|
|
56
|
-
return e.oldValue = O(e.oldValue, !0
|
|
57
|
-
{
|
|
56
|
+
return e.oldValue = O(e.oldValue, !0), e.newValue = O(e.newValue, !1), {
|
|
58
57
|
merged: r,
|
|
59
58
|
delta: e = e.oldValue || e.newValue ? e : void 0
|
|
60
59
|
};
|
|
@@ -65,7 +64,7 @@ function t(r, n, e) {
|
|
|
65
64
|
let l = r;
|
|
66
65
|
for (let r = 0; r < n.length - 1; ++r) {
|
|
67
66
|
var t = n[r];
|
|
68
|
-
|
|
67
|
+
f(l[t]) || (l[t] = {}), l = l[t];
|
|
69
68
|
}
|
|
70
69
|
var u = n.at(-1);
|
|
71
70
|
return void 0 === e ? delete l[u] : l[u] = e, r;
|
|
@@ -83,7 +82,7 @@ function v(r, n, e = !1, l = 0) {
|
|
|
83
82
|
var t = n[l];
|
|
84
83
|
if (l == n.length - 1) return delete r[t], !e && i(r) ? void 0 : r;
|
|
85
84
|
var u = r[t];
|
|
86
|
-
if (
|
|
85
|
+
if (f(u)) {
|
|
87
86
|
u = v(u, n, e, l + 1);
|
|
88
87
|
if (null == u && !e) return delete r[t], i(r) ? void 0 : r;
|
|
89
88
|
r[t] = u;
|
|
@@ -91,25 +90,24 @@ function v(r, n, e = !1, l = 0) {
|
|
|
91
90
|
return r;
|
|
92
91
|
}
|
|
93
92
|
|
|
94
|
-
function O(r, n = !0
|
|
95
|
-
return function e(l, t
|
|
93
|
+
function O(r, n = !0) {
|
|
94
|
+
return function e(l, t) {
|
|
96
95
|
if (l instanceof Date) return l.toISOString();
|
|
97
|
-
if (!
|
|
96
|
+
if (!f(l)) return t && l === m ? void 0 : l;
|
|
98
97
|
if (t) {
|
|
99
98
|
let r = l[w];
|
|
100
|
-
if (null != r) return e(r, t
|
|
99
|
+
if (null != r) return e(r, t);
|
|
101
100
|
let n = l[y];
|
|
102
|
-
if (null != n) return e(p(n) ? n : [ n ], t
|
|
101
|
+
if (null != n) return e(p(n) ? n : [ n ], t);
|
|
103
102
|
}
|
|
104
103
|
let n = p(l);
|
|
105
|
-
let
|
|
106
|
-
for (var
|
|
107
|
-
let r = e(l[
|
|
108
|
-
|
|
109
|
-
i = !1);
|
|
104
|
+
let u = !0;
|
|
105
|
+
for (var i in l) {
|
|
106
|
+
let r = e(l[i], t);
|
|
107
|
+
void 0 === r ? (delete l[i], n && g(l)) : (l[i] = r, u = !1);
|
|
110
108
|
}
|
|
111
|
-
return
|
|
112
|
-
}(r, n
|
|
109
|
+
return u ? void 0 : l;
|
|
110
|
+
}(r, n);
|
|
113
111
|
}
|
|
114
112
|
|
|
115
113
|
function l(r) {
|
|
@@ -122,8 +120,8 @@ function l(r) {
|
|
|
122
120
|
}
|
|
123
121
|
|
|
124
122
|
function S(n, e, l, t, u) {
|
|
125
|
-
if (
|
|
126
|
-
if (e !== m) {
|
|
123
|
+
if (void 0 === e) return n;
|
|
124
|
+
if (e !== m && null !== e) {
|
|
127
125
|
if (null == n || h(n) || h(e)) return j(n, e, l, u);
|
|
128
126
|
var i = e[w];
|
|
129
127
|
if (null != i) return j(n, i, l, u);
|
|
@@ -175,8 +173,8 @@ function u(r) {
|
|
|
175
173
|
}
|
|
176
174
|
|
|
177
175
|
export {
|
|
178
|
-
|
|
179
|
-
o as
|
|
176
|
+
a as mergeContent,
|
|
177
|
+
o as mergeChanges,
|
|
180
178
|
n as mergeContentAndGenDelta,
|
|
181
179
|
t as setValByNamePath,
|
|
182
180
|
e as getValByNamePath,
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import { deepEqual, partialDeepStrictEqual } from "node:assert/strict";
|
|
3
|
+
import { QyDB } from "../src/QyDB.js";
|
|
4
|
+
import { QyJsonSaver } from "../src/QyJsonSaver.js";
|
|
5
|
+
import { logger } from "../src/QyLogger.js";
|
|
6
|
+
logger.level = "warn";
|
|
7
|
+
test("test QyNorthwind", { skip: false }, async (context) => {
|
|
8
|
+
context.after(async (t) => {
|
|
9
|
+
await qyDB.stop();
|
|
10
|
+
});
|
|
11
|
+
const qyDB = new QyDB("./tmp/QyNorthwind", { dumpStructureAtStart: false });
|
|
12
|
+
const [dbValuesJson] = await Promise.all([new QyJsonSaver("./data").loadFromFile("northwind.json"), qyDB.start()]);
|
|
13
|
+
inputTables(qyDB, dbValuesJson);
|
|
14
|
+
inputEmployeeTerritories(qyDB, dbValuesJson);
|
|
15
|
+
inputOrderDetails(qyDB, dbValuesJson);
|
|
16
|
+
await qyDB.stop();
|
|
17
|
+
await qyDB.start();
|
|
18
|
+
deepEqual(getProductSoldAllPrices(qyDB, dbValuesJson), {
|
|
19
|
+
1: 12788.1,
|
|
20
|
+
2: 16355.96,
|
|
21
|
+
3: 3044,
|
|
22
|
+
4: 8567.900000000001,
|
|
23
|
+
5: 5347.200000000001,
|
|
24
|
+
6: 7137,
|
|
25
|
+
7: 22044.3,
|
|
26
|
+
8: 12772,
|
|
27
|
+
9: 7226.5,
|
|
28
|
+
10: 20867.340000000004,
|
|
29
|
+
11: 12901.77,
|
|
30
|
+
12: 12257.660000000002,
|
|
31
|
+
13: 4960.4400000000005,
|
|
32
|
+
14: 7991.489999999999,
|
|
33
|
+
15: 1784.825,
|
|
34
|
+
16: 17215.775499999996,
|
|
35
|
+
17: 32698.379999999997,
|
|
36
|
+
18: 29171.875,
|
|
37
|
+
19: 5862.619999999998,
|
|
38
|
+
20: 22563.359999999997,
|
|
39
|
+
21: 9104,
|
|
40
|
+
22: 7122.360000000001,
|
|
41
|
+
23: 4601.7,
|
|
42
|
+
24: 4504.365,
|
|
43
|
+
25: 3704.3999999999996,
|
|
44
|
+
26: 19849.144500000002,
|
|
45
|
+
27: 15099.875,
|
|
46
|
+
28: 25696.640000000007,
|
|
47
|
+
29: 80368.672,
|
|
48
|
+
30: 13424.197500000002,
|
|
49
|
+
31: 14920.875,
|
|
50
|
+
32: 8404.16,
|
|
51
|
+
33: 1648.125,
|
|
52
|
+
34: 6350.4,
|
|
53
|
+
35: 13643.999999999998,
|
|
54
|
+
36: 13458.460000000001,
|
|
55
|
+
37: 2688.3999999999996,
|
|
56
|
+
38: 141396.735,
|
|
57
|
+
39: 12294.54,
|
|
58
|
+
40: 17910.63,
|
|
59
|
+
41: 8680.345000000005,
|
|
60
|
+
42: 8575,
|
|
61
|
+
43: 23526.699999999997,
|
|
62
|
+
44: 9915.945000000002,
|
|
63
|
+
45: 4338.175,
|
|
64
|
+
46: 5882.999999999999,
|
|
65
|
+
47: 3958.08,
|
|
66
|
+
48: 1368.7125,
|
|
67
|
+
49: 9244.6,
|
|
68
|
+
50: 3437.6875,
|
|
69
|
+
51: 41819.65,
|
|
70
|
+
52: 3232.9500000000003,
|
|
71
|
+
53: 20574.170000000006,
|
|
72
|
+
54: 4728.2375,
|
|
73
|
+
55: 17426.4,
|
|
74
|
+
56: 42593.06,
|
|
75
|
+
57: 7661.549999999999,
|
|
76
|
+
58: 5881.674999999999,
|
|
77
|
+
59: 71155.7,
|
|
78
|
+
60: 46825.48,
|
|
79
|
+
61: 14352.6,
|
|
80
|
+
62: 47234.97,
|
|
81
|
+
63: 16701.095,
|
|
82
|
+
64: 21957.967500000002,
|
|
83
|
+
65: 13869.890000000001,
|
|
84
|
+
66: 3383,
|
|
85
|
+
67: 2396.8,
|
|
86
|
+
68: 8714,
|
|
87
|
+
69: 21942.36,
|
|
88
|
+
70: 10672.65,
|
|
89
|
+
71: 19551.024999999998,
|
|
90
|
+
72: 24900.13,
|
|
91
|
+
73: 3997.2,
|
|
92
|
+
74: 2432.5,
|
|
93
|
+
75: 8177.489999999999,
|
|
94
|
+
76: 15760.44,
|
|
95
|
+
77: 9171.63,
|
|
96
|
+
});
|
|
97
|
+
for (const tableName in dbValuesJson) {
|
|
98
|
+
if (tableName.indexOf("_") < 0) {
|
|
99
|
+
const table = dbValuesJson[tableName];
|
|
100
|
+
for (const id in table) {
|
|
101
|
+
partialDeepStrictEqual(qyDB.view([tableName, id]), table[id]);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
deepEqual(qyDB.view(["employees", "6"], {
|
|
106
|
+
$all: 1,
|
|
107
|
+
last_name: 0,
|
|
108
|
+
reports_to: { $link: "employees", $spec: { first_name: 1, postal_code: 1 } },
|
|
109
|
+
territories: {
|
|
110
|
+
$link: "territories",
|
|
111
|
+
$spec: { "**": 1, region_id: { $link: "region", region_description: 1 } },
|
|
112
|
+
},
|
|
113
|
+
}), {
|
|
114
|
+
employee_id: 6,
|
|
115
|
+
region: null,
|
|
116
|
+
first_name: "Michael",
|
|
117
|
+
title: "Sales Representative",
|
|
118
|
+
title_of_courtesy: "Mr.",
|
|
119
|
+
birth_date: "1963-07-02",
|
|
120
|
+
hire_date: "1993-10-17",
|
|
121
|
+
address: "Coventry House\\nMiner Rd.",
|
|
122
|
+
city: "London",
|
|
123
|
+
postal_code: "EC2 7JR",
|
|
124
|
+
country: "UK",
|
|
125
|
+
home_phone: "(71) 555-7773",
|
|
126
|
+
extension: "428",
|
|
127
|
+
photo: "\\x",
|
|
128
|
+
notes: "Michael is a graduate of Sussex University (MA, economics, 1983) and the University of California at Los Angeles (MBA, marketing, 1986). He has also taken the courses Multi-Cultural Selling and Time Management for the Sales Professional. He is fluent in Japanese and can read and write French, Portuguese, and Spanish.",
|
|
129
|
+
reports_to: { first_name: "Steven", postal_code: "SW1 8JR" },
|
|
130
|
+
photo_path: "http://accweb/emmployees/davolio.bmp",
|
|
131
|
+
territories: {
|
|
132
|
+
85014: {
|
|
133
|
+
territory_id: "85014",
|
|
134
|
+
territory_description: "Phoenix",
|
|
135
|
+
region_id: { region_id: 2, region_description: "Western" },
|
|
136
|
+
},
|
|
137
|
+
85251: {
|
|
138
|
+
territory_id: "85251",
|
|
139
|
+
territory_description: "Scottsdale",
|
|
140
|
+
region_id: { region_id: 2, region_description: "Western" },
|
|
141
|
+
},
|
|
142
|
+
98004: {
|
|
143
|
+
territory_id: "98004",
|
|
144
|
+
territory_description: "Bellevue",
|
|
145
|
+
region_id: { region_id: 2, region_description: "Western" },
|
|
146
|
+
},
|
|
147
|
+
98052: {
|
|
148
|
+
territory_id: "98052",
|
|
149
|
+
territory_description: "Redmond",
|
|
150
|
+
region_id: { region_id: 2, region_description: "Western" },
|
|
151
|
+
},
|
|
152
|
+
98104: {
|
|
153
|
+
territory_id: "98104",
|
|
154
|
+
territory_description: "Seattle",
|
|
155
|
+
region_id: { region_id: 2, region_description: "Western" },
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
function inputTables(qyDB, dbValuesJson) {
|
|
161
|
+
qyDB.createIndex("customers", ["city", "postal_code", "country"]);
|
|
162
|
+
const { batch } = qyDB;
|
|
163
|
+
for (const tableName in dbValuesJson) {
|
|
164
|
+
if (tableName.indexOf("_") < 0) {
|
|
165
|
+
logger.log(`inserting ${tableName}`);
|
|
166
|
+
const table = dbValuesJson[tableName];
|
|
167
|
+
batch.cd(["/", tableName]);
|
|
168
|
+
for (const id in table) {
|
|
169
|
+
batch.insert(id, table[id]);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
batch.run();
|
|
174
|
+
}
|
|
175
|
+
function inputEmployeeTerritories(qyDB, dbValuesJson) {
|
|
176
|
+
const employeeTerritoriesTable = dbValuesJson.employee_territories;
|
|
177
|
+
const { batch } = qyDB;
|
|
178
|
+
batch.cd("employees");
|
|
179
|
+
for (const prop in employeeTerritoriesTable) {
|
|
180
|
+
const { employee_id, territory_id } = employeeTerritoriesTable[prop];
|
|
181
|
+
batch.insert(`${employee_id}`, { territories: { [territory_id]: 1 } });
|
|
182
|
+
}
|
|
183
|
+
batch.run();
|
|
184
|
+
}
|
|
185
|
+
function inputOrderDetails(qyDB, dbValuesJson) {
|
|
186
|
+
qyDB.createIndex("orderDetails", ["order_id", "product_id"]);
|
|
187
|
+
const orderDetailsTable = dbValuesJson.order_details;
|
|
188
|
+
const { batch } = qyDB;
|
|
189
|
+
batch.cd("orderDetails");
|
|
190
|
+
for (const key in orderDetailsTable) {
|
|
191
|
+
batch.insert(`${key}`, orderDetailsTable[key]);
|
|
192
|
+
}
|
|
193
|
+
batch.run();
|
|
194
|
+
}
|
|
195
|
+
function getProductSoldAllPrices(qyDB, dbValuesJson) {
|
|
196
|
+
const totalPriceMap = {};
|
|
197
|
+
for (const product_id in dbValuesJson.products) {
|
|
198
|
+
let totalPrices = 0;
|
|
199
|
+
qyDB.queryFiles("orderDetails", { product_id }).forEach((x) => {
|
|
200
|
+
const { unit_price, quantity, discount } = x.view();
|
|
201
|
+
totalPrices += unit_price * quantity * (1 - discount);
|
|
202
|
+
});
|
|
203
|
+
totalPriceMap[product_id] = totalPrices;
|
|
204
|
+
}
|
|
205
|
+
return totalPriceMap;
|
|
206
|
+
}
|