(core) Clean up and refactor uses of HomeDBManager.getDoc

Summary:
Firstly I just wanted some more consistency and less repetition in places where Documents are retrieved from the DB, so it's more obvious when code differs from the norm. Main changes for that part:

- Let HomeDBManager accept a `Request` directly and convert it to a `Scope`, and use this in a few places.
- `getScope` tries `req.docAuth.docId` if `req.params` doesn't have a docId.

I also refactored how `_createActiveDoc` gets the document URL, separating out getting the document from getting a URL for it. This is because I want to use that document object in a future diff, but I also just find it cleaner. Notable changes for that:

- Extracted a new method `HomeDBManager.getRawDocById` as an alternative to `getDoc` that's explicitly for when you only have a document ID.
- Removed the interface method `GristServer.getDocUrl` and its two implementations because it wasn't used elsewhere and it didn't really add anything on top of getting a doc (now done by `getRawDocById`) and `getResourceUrl`.
- Between `cachedDoc` and `getRawDocById` (which represent previously existing code paths) also try `getDoc(getScope(docSession.req))`, which is new, because it seems better to only `getRawDocById` as a last resort.

Test Plan: Existing tests

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3328
This commit is contained in:
Alex Hall
2022-03-24 12:59:47 +02:00
parent b1c3943bf4
commit 546096fcc9
8 changed files with 147 additions and 92 deletions

View File

@@ -1,4 +1,6 @@
import * as pidusage from '@gristlabs/pidusage';
import {Document} from 'app/gen-server/entity/Document';
import {getScope} from 'app/server/lib/requestUtils';
import * as bluebird from 'bluebird';
import {EventEmitter} from 'events';
import * as path from 'path';
@@ -464,23 +466,50 @@ export class DocManager extends EventEmitter {
return activeDoc;
}
private async _createActiveDoc(docSession: OptDocSession, docName: string, safeMode?: boolean) {
// Get URL for document for use with SELF_HYPERLINK().
private async _getDoc(docSession: OptDocSession, docName: string) {
const cachedDoc = getDocSessionCachedDoc(docSession);
let docUrl: string|undefined;
if (cachedDoc) {
return cachedDoc;
}
let db: HomeDBManager;
try {
if (cachedDoc) {
docUrl = await this.gristServer.getResourceUrl(cachedDoc);
} else {
docUrl = await this.gristServer.getDocUrl(docName);
// For the sake of existing tests, get the db from gristServer where it may not exist and we should give up,
// rather than using this._homeDbManager which may exist and then it turns out the document itself doesn't.
db = this.gristServer.getHomeDBManager();
} catch (e) {
if (e.message === "no db") {
return;
}
throw e;
}
if (docSession.req) {
const scope = getScope(docSession.req);
if (scope.urlId) {
return db.getDoc(scope);
}
}
return await db.getRawDocById(docName);
}
private async _getDocUrl(doc: Document) {
try {
return await this.gristServer.getResourceUrl(doc);
} catch (e) {
// If there is no home url, we cannot construct links. Accept this, for the benefit
// of legacy tests.
if (!String(e).match(/need APP_HOME_URL/)) {
if (e.message !== "need APP_HOME_URL") {
throw e;
}
}
}
private async _createActiveDoc(docSession: OptDocSession, docName: string, safeMode?: boolean) {
const doc = await this._getDoc(docSession, docName);
// Get URL for document for use with SELF_HYPERLINK().
const docUrl = doc && await this._getDocUrl(doc);
return this.gristServer.create.ActiveDoc(this, docName, {docUrl, safeMode});
}