datafolder 1.0.15 → 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 +4 -0
- package/data/northwind.json +31945 -0
- package/package.json +3 -2
- package/src/QyAcl.js +1 -1
- package/src/QyExpire.js +1 -3
- package/src/QyFileContentUtils.d.ts +2 -2
- package/src/QyFileContentUtils.js +22 -24
- package/static/codemirror.bundle/editor.bundle.js +93 -38
- package/test/testQyGraphQL.js +198 -0
- package/test/testQyNorthwind.js +206 -0
|
@@ -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
|
+
}
|