Skip to content

Commit 87ec12f

Browse files
committed
adding export relation
1 parent 06bceb6 commit 87ec12f

File tree

1 file changed

+123
-70
lines changed

1 file changed

+123
-70
lines changed

src/Routers/ExportRouter.js

Lines changed: 123 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,30 @@ import tmp from 'tmp';
77
import fs from 'fs';
88

99
const DefaultExportExportProgressCollectionName = "_ExportProgress";
10+
const relationSchema = { fields: { relatedId: { type: 'String' }, owningId: { type: 'String' } } };
1011

1112
export class ExportRouter extends PromiseRouter {
1213

13-
handleExportProgress(req) {
1414

15-
const databaseController = req.config.database;
1615

17-
let query = {
18-
masterKey: req.info.masterKey,
19-
applicationId: req.info.appId
20-
};
16+
exportClassPage(req, name, jsonFileStream, where, skip, limit) {
2117

22-
return databaseController.find(DefaultExportExportProgressCollectionName, query)
23-
.then((response) => {
24-
return { response };
25-
});
26-
}
18+
const databaseController = req.config.database;
2719

28-
handleExportPage(req, name, jsonFileStream, where, skip, limit) {
2920
let options = {
3021
skip,
3122
limit
3223
};
3324

34-
return rest.find(req.config, req.auth, name, where, options)
25+
let findPromise = name.indexOf('_Join') === 0 ?
26+
databaseController.adapter.find(name, relationSchema, where, options)
27+
: rest.find(req.config, req.auth, name, where, options);
28+
29+
return findPromise
3530
.then((data) => {
31+
if (Array.isArray(data)) {
32+
data = { results : data };
33+
}
3634

3735
if (skip && data.results.length) {
3836
jsonFileStream.write(',\n');
@@ -42,35 +40,26 @@ export class ExportRouter extends PromiseRouter {
4240
});
4341
}
4442

45-
handleExport(req) {
43+
exportClass(req, data) {
4644

47-
const databaseController = req.config.database;
48-
let data = req.body;
4945

46+
const databaseController = req.config.database;
5047
let tmpJsonFile = tmp.fileSync();
5148
let jsonFileStream = fs.createWriteStream(tmpJsonFile.name);
5249

5350
jsonFileStream.write('{\n"results" : [\n');
5451

55-
let exportProgress = {
56-
id: data.name,
57-
masterKey: req.info.masterKey,
58-
applicationId: req.info.appId
59-
};
60-
52+
let findPromise = data.name.indexOf('_Join') === 0 ?
53+
databaseController.adapter.count(data.name, relationSchema, data.where)
54+
: rest.find(req.config, req.auth, data.name, data.where, { count: true, limit: 0 });
6155

62-
let emailControllerAdapter = req.config.emailControllerAdapter;
63-
64-
if (!emailControllerAdapter) {
65-
return Promise.reject(new Error('You have to setup a Mail Adapter.'));
66-
}
67-
68-
databaseController.create(DefaultExportExportProgressCollectionName, exportProgress)
69-
.then(() => {
70-
return rest.find(req.config, req.auth, data.name, data.where, { count: true, limit: 0 });
71-
})
56+
return findPromise
7257
.then((result) => {
7358

59+
if (Number.isInteger(result)) {
60+
result = { count: result };
61+
}
62+
7463
let i = 0;
7564
let pageLimit = 1000;
7665
let promise = Promise.resolve();
@@ -80,7 +69,7 @@ export class ExportRouter extends PromiseRouter {
8069

8170
let skip = i;
8271
promise = promise.then(() => {
83-
return this.handleExportPage(req, data.name, jsonFileStream, data.where, skip, pageLimit);
72+
return this.exportClassPage(req, data.name, jsonFileStream, data.where, skip, pageLimit);
8473
});
8574
}
8675

@@ -93,54 +82,118 @@ export class ExportRouter extends PromiseRouter {
9382
return new Promise((resolve, reject) => {
9483

9584
jsonFileStream.on('close', () => {
85+
tmpJsonFile._name = `${data.name.replace(':', '/')}.json`;
86+
87+
resolve(tmpJsonFile);
88+
});
89+
})
90+
});
91+
}
92+
93+
handleExportProgress(req) {
94+
95+
const databaseController = req.config.database;
96+
97+
let query = {
98+
masterKey: req.info.masterKey,
99+
applicationId: req.info.appId
100+
};
96101

97-
let tmpZipFile = tmp.fileSync();
98-
let tmpZipStream = fs.createWriteStream(tmpZipFile.name);
102+
return databaseController.find(DefaultExportExportProgressCollectionName, query)
103+
.then((response) => {
104+
return { response };
105+
});
106+
}
99107

100-
let zip = archiver('zip', { store: true });
101-
zip.pipe(tmpZipStream);
102-
zip.append(fs.readFileSync(tmpJsonFile.name), { name: `${data.name}.json` });
103-
zip.finalize();
108+
handleExport(req) {
104109

105-
tmpJsonFile.removeCallback();
110+
const databaseController = req.config.database;
106111

107-
tmpZipStream.on('close', () => {
112+
let emailControllerAdapter = req.config.emailControllerAdapter;
108113

109-
let buf = fs.readFileSync(tmpZipFile.name);
110-
tmpZipFile.removeCallback();
111-
resolve(buf);
114+
if (!emailControllerAdapter) {
115+
return Promise.reject(new Error('You have to setup a Mail Adapter.'));
116+
}
112117

113-
});
118+
let exportProgress = {
119+
id: req.body.name,
120+
masterKey: req.info.masterKey,
121+
applicationId: req.info.appId
122+
};
114123

115-
});
116-
})
117-
})
118-
.then((zippedFile) => {
119-
const filesController = req.config.filesController;
120-
return filesController.createFile(req.config, data.name, zippedFile, 'application/zip');
121-
})
122-
.then((fileData) => {
123-
124-
return emailControllerAdapter.sendMail({
125-
text: `We have successfully exported your data from the class ${data.name}.\n
126-
Please download from ${fileData.url}`,
127-
link: fileData.url,
128-
to: req.body.feedbackEmail,
129-
subject: 'Export completed'
124+
databaseController.create(DefaultExportExportProgressCollectionName, exportProgress)
125+
.then(() => {
126+
return databaseController.loadSchema({ clearCache: true});
127+
})
128+
.then(schemaController => schemaController.getOneSchema(req.body.name, true))
129+
.then((schema) => {
130+
let classNames = [ req.body.name ];
131+
Object.keys(schema.fields).forEach((fieldName) => {
132+
let field = schema.fields[fieldName];
133+
134+
if (field.type === 'Relation') {
135+
classNames.push(`_Join:${fieldName}:${req.body.name}`);
136+
}
137+
});
138+
139+
let promisses = classNames.map((name) => {
140+
return this.exportClass(req, { name });
141+
});
142+
143+
return Promise.all(promisses)
144+
})
145+
.then((jsonFiles) => {
146+
147+
return new Promise((resolve) => {
148+
let tmpZipFile = tmp.fileSync();
149+
let tmpZipStream = fs.createWriteStream(tmpZipFile.name);
150+
151+
let zip = archiver('zip', { store: true });
152+
zip.pipe(tmpZipStream);
153+
154+
jsonFiles.forEach(tmpJsonFile => {
155+
zip.append(fs.readFileSync(tmpJsonFile.name), { name: tmpJsonFile._name });
156+
tmpJsonFile.removeCallback();
130157
});
131-
})
132-
.catch((error) => {
133-
return emailControllerAdapter.sendMail({
134-
text: `We could not export your data to the class ${data.name}. Error: ${error}`,
135-
to: req.body.feedbackEmail,
136-
subject: 'Export failed'
158+
159+
zip.finalize();
160+
161+
tmpZipStream.on('close', () => {
162+
163+
let buf = fs.readFileSync(tmpZipFile.name);
164+
tmpZipFile.removeCallback();
165+
resolve(buf);
166+
137167
});
138-
})
139-
.then(() => {
140-
return databaseController.destroy(DefaultExportExportProgressCollectionName, exportProgress);
141168
});
142169

143-
return Promise.resolve({response: 'We are exporting your data. You will be notified by e-mail once it is completed.'});
170+
})
171+
.then((zippedFile) => {
172+
const filesController = req.config.filesController;
173+
return filesController.createFile(req.config, req.body.name, zippedFile, 'application/zip');
174+
})
175+
.then((fileData) => {
176+
177+
return emailControllerAdapter.sendMail({
178+
text: `We have successfully exported your data from the class ${req.body.name}.\n
179+
Please download from ${fileData.url}`,
180+
link: fileData.url,
181+
to: req.body.feedbackEmail,
182+
subject: 'Export completed'
183+
});
184+
})
185+
.catch((error) => {
186+
return emailControllerAdapter.sendMail({
187+
text: `We could not export your data to the class ${data.name}. Error: ${error}`,
188+
to: req.body.feedbackEmail,
189+
subject: 'Export failed'
190+
});
191+
})
192+
.then(() => {
193+
return databaseController.destroy(DefaultExportExportProgressCollectionName, exportProgress);
194+
});
195+
196+
return Promise.resolve({response: 'We are exporting your data. You will be notified by e-mail once it is completed.'});
144197
}
145198

146199
mountRoutes() {

0 commit comments

Comments
 (0)