@social-mail/social-mail-web-server 1.7.537 → 1.7.539
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/dist/server/seed/ui/seed-ui.js +1 -1
- package/dist/server/services/files/FilePathService.d.ts.map +1 -1
- package/dist/server/services/files/FilePathService.js +18 -11
- package/dist/server/services/files/FilePathService.js.map +1 -1
- package/dist/server/workflows/files/DeleteFileWorkflow.d.ts +3 -4
- package/dist/server/workflows/files/DeleteFileWorkflow.d.ts.map +1 -1
- package/dist/server/workflows/files/DeleteFileWorkflow.js +139 -38
- package/dist/server/workflows/files/DeleteFileWorkflow.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/server/seed/ui/seed-ui.ts +1 -1
- package/src/server/services/files/FilePathService.ts +19 -14
- package/src/server/workflows/files/DeleteFileWorkflow.ts +95 -46
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@ export default async function seedUI(config: DBConfig) {
|
|
|
5
5
|
await config.saveVersion(UIPackageConfig, {
|
|
6
6
|
package: "@social-mail/social-mail-client",
|
|
7
7
|
view: "dist/web/AppIndex",
|
|
8
|
-
version: "1.8.
|
|
8
|
+
version: "1.8.111"
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
await config.saveVersion(WebComponentsPackageConfig, {
|
|
@@ -10,25 +10,30 @@ export default class FilePathService {
|
|
|
10
10
|
db: SocialMailContext;
|
|
11
11
|
|
|
12
12
|
async update(entity: AppFile) {
|
|
13
|
+
const { db } = this;
|
|
13
14
|
const { parentID, isFolder } = entity;
|
|
15
|
+
let root = null;
|
|
14
16
|
if (parentID) {
|
|
15
|
-
await
|
|
16
|
-
.
|
|
17
|
-
|
|
17
|
+
const [ { path }] = await db.appFiles.where(entity, (p) => (x) => x.appFileID === p.appFileID)
|
|
18
|
+
.updateSelect(void 0, (p) => (x) => ({ path: `${x.parent.path}${Sql.cast.asText(x.appFileID)}/` }));
|
|
19
|
+
root = path + "%";
|
|
18
20
|
} else if (isFolder) {
|
|
19
|
-
await
|
|
20
|
-
.
|
|
21
|
+
const [{ path }] = await db.appFiles.where(entity, (p) => (x) => x.appFileID === p.appFileID)
|
|
22
|
+
.updateSelect(void 0, (p) => (x) => ({ path: `${Sql.cast.asText(x.appFileID)}/` }));
|
|
23
|
+
root = path + "%";
|
|
21
24
|
}
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
// following logic will recursively set all path correctly for every nested level
|
|
27
|
+
// this should run in a single transaction to avoid conflicts
|
|
28
|
+
|
|
29
|
+
for(;;) {
|
|
30
|
+
const n = await db.appFiles.where({ root }, (p) => (x) => !Sql.text.like(x.path, p.root) && Sql.text.like(x.parent.path, p.root))
|
|
31
|
+
.update(void 0, (p) => (x) => ({
|
|
32
|
+
path: `${x.parent.path}${x.appFileID}/`,
|
|
33
|
+
}));
|
|
34
|
+
if (!n) {
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
}
|
|
@@ -7,82 +7,131 @@ import Sql from "@entity-access/entity-access/dist/sql/Sql.js";
|
|
|
7
7
|
export default class DeleteFileWorkflow extends Workflow<{ fileID }> {
|
|
8
8
|
|
|
9
9
|
path: string;
|
|
10
|
+
root: string;
|
|
10
11
|
|
|
11
12
|
async run() {
|
|
12
13
|
|
|
14
|
+
// mark the file as deleted and remove from parent
|
|
15
|
+
this.root = await this.markDeleted();
|
|
16
|
+
|
|
13
17
|
let start = 0;
|
|
14
18
|
for(;;) {
|
|
15
19
|
|
|
16
|
-
|
|
17
|
-
start
|
|
18
|
-
if (!start) {
|
|
20
|
+
start = await this.deleteFiles(start, false);
|
|
21
|
+
if (!BigInt(start)) {
|
|
19
22
|
break;
|
|
20
23
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
start = 0;
|
|
27
|
+
for(;;) {
|
|
28
|
+
|
|
29
|
+
start = await this.deleteFiles(start, true);
|
|
30
|
+
if (!BigInt(start)) {
|
|
31
|
+
break;
|
|
25
32
|
}
|
|
26
33
|
}
|
|
27
34
|
|
|
35
|
+
|
|
28
36
|
await this.deleteFile();
|
|
29
37
|
|
|
30
38
|
}
|
|
31
39
|
|
|
32
40
|
@UniqueActivity
|
|
33
|
-
async
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
async deleteFiles(
|
|
42
|
+
start,
|
|
43
|
+
isFolder,
|
|
44
|
+
@Inject db?: SocialMailContext) {
|
|
45
|
+
const { root } = this;
|
|
46
|
+
for (let index = 0; index < 100; index++) {
|
|
47
|
+
|
|
48
|
+
db.changeSet.clear();
|
|
49
|
+
|
|
50
|
+
const q = db.appFiles
|
|
51
|
+
.where({ start, root, isFolder }, (p) => (x) =>
|
|
52
|
+
Sql.text.like(x.path, p.root)
|
|
53
|
+
&& x.isFolder === p.isFolder
|
|
54
|
+
&& x.appFileID > p.start)
|
|
55
|
+
.orderBy(void 0, (p) => (x) => x.appFileID)
|
|
56
|
+
.limit(20);
|
|
57
|
+
|
|
58
|
+
if (isFolder) {
|
|
59
|
+
const n = await q.delete(void 0, (p) => (x) => x.isFolder === true);
|
|
60
|
+
if (!n) {
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const files = await db.appFiles
|
|
67
|
+
.where({ start, root, isFolder }, (p) => (x) =>
|
|
68
|
+
Sql.text.like(x.path, p.root)
|
|
69
|
+
&& x.isFolder === p.isFolder
|
|
70
|
+
&& x.appFileID > p.start)
|
|
71
|
+
.orderBy(void 0, (p) => (x) => x.appFileID)
|
|
72
|
+
.limit(20)
|
|
73
|
+
.toArray();
|
|
74
|
+
|
|
75
|
+
if (!files.length) {
|
|
76
|
+
return 0;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for (const { appFileID } of files) {
|
|
80
|
+
start = appFileID;
|
|
81
|
+
await db.fileContents.where({ appFileID }, (p) => (x) =>
|
|
82
|
+
x.appFiles.some((f) => f.appFileID === p.appFileID)
|
|
83
|
+
|| x.versions.some((v) => v.fileID === p.appFileID))
|
|
84
|
+
.update(void 0, (p) => (x) => ({ deleted: true }));
|
|
85
|
+
await db.fileVersions.asQuery()
|
|
86
|
+
.delete({ appFileID }, (p) => (x) => x.fileID === p.appFileID);
|
|
87
|
+
await db.appFiles.statements.delete({ appFileID });
|
|
40
88
|
}
|
|
41
|
-
await db.websiteFolders.statements.delete({ folderID: site.folderID });
|
|
42
89
|
}
|
|
43
|
-
|
|
90
|
+
return start;
|
|
44
91
|
}
|
|
45
92
|
|
|
46
93
|
@UniqueActivity
|
|
47
|
-
async
|
|
48
|
-
|
|
49
|
-
@Inject db?: SocialMailContext
|
|
50
|
-
) {
|
|
51
|
-
const { fileID } = this.input;
|
|
52
|
-
const files = await db.appFiles
|
|
53
|
-
.where({ fileID , start }, (p) => (x) =>
|
|
54
|
-
x.parentID === p.fileID
|
|
55
|
-
&& x.appFileID > p.start)
|
|
56
|
-
.orderBy(void 0, (p) => (x) => x.appFileID)
|
|
57
|
-
.limit(20)
|
|
58
|
-
.toArray();
|
|
94
|
+
async markDeleted(@Inject db?: SocialMailContext) {
|
|
95
|
+
const { fileID: appFileID } = this.input;
|
|
59
96
|
|
|
60
|
-
|
|
97
|
+
await using tx = await db.connection.createTransaction();
|
|
61
98
|
|
|
62
|
-
|
|
63
|
-
return { start: 0, children };
|
|
64
|
-
}
|
|
99
|
+
const now = Date.now();
|
|
65
100
|
|
|
66
|
-
|
|
67
|
-
start = appFileID;
|
|
101
|
+
let root = `x-${now.toString(36)}/${appFileID}/`;
|
|
68
102
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
103
|
+
await db.appFiles.statements.update({ parentID: null, path: root, isDeleted: true }, { appFileID });
|
|
104
|
+
|
|
105
|
+
root += "%";
|
|
106
|
+
|
|
107
|
+
for(;;) {
|
|
108
|
+
const n = await db.appFiles.where({ root }, (p) => (x) => !Sql.text.like(x.path, p.root) && Sql.text.like(x.parent.path, p.root))
|
|
109
|
+
.update(void 0, (p) => (x) => ({
|
|
110
|
+
path: `${x.parent.path}${x.appFileID}/`,
|
|
111
|
+
isDeleted: true
|
|
112
|
+
}));
|
|
113
|
+
if (!n) {
|
|
114
|
+
break;
|
|
72
115
|
}
|
|
116
|
+
}
|
|
73
117
|
|
|
74
|
-
|
|
75
|
-
x.appFiles.some((f) => f.appFileID === p.appFileID)
|
|
76
|
-
|| x.versions.some((v) => v.fileID === p.appFileID))
|
|
77
|
-
.update(void 0, (p) => (x) => ({ deleted: true }));
|
|
118
|
+
await tx.commit();
|
|
78
119
|
|
|
79
|
-
|
|
80
|
-
|
|
120
|
+
return root;
|
|
121
|
+
}
|
|
81
122
|
|
|
82
|
-
|
|
123
|
+
@UniqueActivity
|
|
124
|
+
async deleteFile(@Inject db?: SocialMailContext) {
|
|
125
|
+
await db.websiteVersions.asQuery().delete(this.input, (p) => (x) => x.snapshotFolderID === p.fileID);
|
|
126
|
+
const site = await db.websiteFolders.statements.select({}, { folderID: this.input.fileID });
|
|
127
|
+
if (site) {
|
|
128
|
+
if (site.currentTemplateID) {
|
|
129
|
+
await db.websiteFolders.where(site, (p) => (x) => x.folderID === p.currentTemplateID && x.isTemplate === true)
|
|
130
|
+
.update(this.input, (p) => (x) => ({ templateSites: Sql.math.max(0, x.templateSites -1) }));
|
|
131
|
+
}
|
|
132
|
+
await db.websiteFolders.statements.delete({ folderID: site.folderID });
|
|
83
133
|
}
|
|
84
|
-
|
|
85
|
-
return { start, children };
|
|
134
|
+
await db.appFiles.statements.delete({ appFileID: this.input.fileID});
|
|
86
135
|
}
|
|
87
136
|
|
|
88
137
|
|