Skip to content

Commit 26f7eb7

Browse files
authored
fix(VSCODE-118): Enable opening documents with binary _id from tree view (#213)
1 parent 3320243 commit 26f7eb7

File tree

7 files changed

+75
-28
lines changed

7 files changed

+75
-28
lines changed

package-lock.json

Lines changed: 4 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,7 @@
827827
"@mongosh/service-provider-server": "^0.5.2",
828828
"@mongosh/shell-api": "^0.5.2",
829829
"analytics-node": "^3.4.0-beta.1",
830-
"bson": "^4.0.3",
830+
"bson": "^4.2.0",
831831
"classnames": "^2.2.6",
832832
"debug": "^4.1.1",
833833
"dotenv": "^8.2.0",

src/editors/documentProvider.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ export default class DocumentViewProvider implements vscode.TextDocumentContentP
3636
const documentIdEJSONString = decodeURIComponent(
3737
uriParams.get(DOCUMENT_ID_URI_IDENTIFIER) || ''
3838
);
39-
const documentId = EJSON.parse(documentIdEJSONString).value;
39+
40+
const jsonObjectId = JSON.parse(documentIdEJSONString).value;
41+
const documentId = EJSON.deserialize(jsonObjectId);
4042

4143
// Ensure we're still connected to the correct connection.
4244
if (connectionId !== this._connectionController.getActiveConnectionId()) {
@@ -77,7 +79,7 @@ export default class DocumentViewProvider implements vscode.TextDocumentContentP
7779
}
7880

7981
if (!documents || documents.length === 0) {
80-
const errorMessage = `Unable to find document: ${documentId}`;
82+
const errorMessage = `Unable to find document: ${JSON.stringify(jsonObjectId)}`;
8183
vscode.window.showErrorMessage(errorMessage);
8284
return reject(new Error(errorMessage));
8385
}

src/editors/editorsController.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,15 @@ export default class EditorsController {
9999
log.info('activated.');
100100
}
101101

102-
onViewDocument(namespace: string, documentId: any): Promise<boolean> {
102+
onViewDocument(namespace: string, documentId: EJSON.SerializableTypes): Promise<boolean> {
103103
log.info('view document in editor', namespace);
104104

105105
const connectionId = this._connectionController.getActiveConnectionId();
106106
const connectionIdUriQuery = `${CONNECTION_ID_URI_IDENTIFIER}=${connectionId}`;
107107
// Encode the _id field incase the document id is a custom string with
108108
// special characters.
109-
const documentIdString = EJSON.stringify({
110-
value: documentId
109+
const documentIdString = JSON.stringify({
110+
value: EJSON.serialize(documentId)
111111
});
112112

113113
const documentIdUriQuery = `${DOCUMENT_ID_URI_IDENTIFIER}=${encodeURIComponent(

src/explorer/documentTreeItem.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { EJSON } from 'bson';
12
import * as vscode from 'vscode';
23

34
export const DOCUMENT_ITEM = 'documentTreeItem';
@@ -6,11 +7,9 @@ export default class DocumentTreeItem extends vscode.TreeItem
67
implements vscode.TreeDataProvider<DocumentTreeItem> {
78
contextValue = DOCUMENT_ITEM;
89

9-
private _documentLabel: string;
10-
1110
namespace: string;
1211
document: any;
13-
documentId: string;
12+
documentId: EJSON.SerializableTypes;
1413

1514
constructor(document: any, namespace: string, documentIndexInTree: number) {
1615
// A document can not have a `_id` when it is in a view. In this instance
@@ -25,7 +24,6 @@ export default class DocumentTreeItem extends vscode.TreeItem
2524
const documentLabel = document._id
2625
? JSON.stringify(document._id)
2726
: `Document ${documentIndexInTree + 1}`;
28-
this._documentLabel = documentLabel;
2927

3028
this.document = document;
3129
this.documentId = document._id;

src/test/suite/editors/documentProvider.test.ts

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ import {
1616
} from '../dbTestHelper';
1717
import {
1818
documentWithAllBSONTypes,
19-
documentWithAllBsonTypesJsonified
19+
documentWithAllBsonTypesJsonified,
20+
documentWithBinaryId,
21+
documentWithBinaryIdString
2022
} from './documentStringFixtures';
2123

2224
const mockDocumentAsJsonString = `{
@@ -139,7 +141,7 @@ suite('Document Provider Test Suite', () => {
139141
.then((document) => {
140142
assert(
141143
document === mockDocumentAsJsonString,
142-
`Expected provideTextDocumentContent to return ejson stringified string, found ${document}`
144+
`Expected provideTextDocumentContent to return json stringified string, found ${document}`
143145
);
144146
done();
145147
})
@@ -212,7 +214,9 @@ suite('Document Provider Test Suite', () => {
212214
});
213215

214216
test('handles displaying a document with all bson types', (done) => {
215-
seedDataAndCreateDataService('ramen', [documentWithAllBSONTypes]).then(
217+
seedDataAndCreateDataService('ramen', [
218+
documentWithAllBSONTypes
219+
]).then(
216220
(dataService) => {
217221
const mockExtensionContext = new TestExtensionContext();
218222
const mockStorageController = new StorageController(
@@ -236,7 +240,7 @@ suite('Document Provider Test Suite', () => {
236240
);
237241

238242
const documentId = EJSON.stringify({
239-
value: documentWithAllBSONTypes._id
243+
value: (documentWithAllBSONTypes as any)._id
240244
});
241245
const uri = vscode.Uri.parse(
242246
`scheme:Results: filename.json?namespace=${TEST_DB_NAME}.ramen&documentId=${documentId}`
@@ -247,7 +251,7 @@ suite('Document Provider Test Suite', () => {
247251
.then((document) => {
248252
assert(
249253
document === documentWithAllBsonTypesJsonified,
250-
`Expected provideTextDocumentContent to return ejson stringified string, found ${document}`
254+
`Expected provideTextDocumentContent to return json stringified string, found ${document}`
251255
);
252256
done();
253257
})
@@ -256,6 +260,46 @@ suite('Document Provider Test Suite', () => {
256260
);
257261
});
258262

263+
test('can find a doc with a binary _id', async () => {
264+
const dataService = await seedDataAndCreateDataService('ramen', [
265+
documentWithBinaryId
266+
]);
267+
const mockExtensionContext = new TestExtensionContext();
268+
const mockStorageController = new StorageController(
269+
mockExtensionContext
270+
);
271+
const testTelemetryController = new TelemetryController(
272+
mockStorageController,
273+
mockExtensionContext
274+
);
275+
const mockConnectionController = new ConnectionController(
276+
new StatusView(mockExtensionContext),
277+
mockStorageController,
278+
testTelemetryController
279+
);
280+
281+
mockConnectionController.setActiveConnection(dataService);
282+
283+
const testCollectionViewProvider = new DocumentProvider(
284+
mockConnectionController,
285+
new StatusView(mockExtensionContext)
286+
);
287+
288+
const documentId = EJSON.stringify({
289+
value: documentWithBinaryId._id
290+
});
291+
const uri = vscode.Uri.parse(
292+
`scheme:Results: filename.json?namespace=${TEST_DB_NAME}.ramen&documentId=${documentId}`
293+
);
294+
295+
const document = await testCollectionViewProvider
296+
.provideTextDocumentContent(uri);
297+
assert(
298+
document === documentWithBinaryIdString,
299+
`Expected provideTextDocumentContent to return json stringified string ${documentWithBinaryIdString}, found ${document}`
300+
);
301+
});
302+
259303
test('expected provideTextDocumentContent to handle an id that is an object id', (done) => {
260304
const mockDocument = {
261305
_id: new ObjectId('5e32b4d67bf47f4525f2f8ab'),
@@ -297,7 +341,7 @@ suite('Document Provider Test Suite', () => {
297341
.then((document) => {
298342
assert(
299343
document === docAsString2,
300-
`Expected provideTextDocumentContent to return ejson stringified string, found ${document}`
344+
`Expected provideTextDocumentContent to return json stringified string, found ${document}`
301345
);
302346
done();
303347
})
@@ -347,7 +391,7 @@ suite('Document Provider Test Suite', () => {
347391
.then((document) => {
348392
assert(
349393
document === docAsString3,
350-
`Expected provideTextDocumentContent to return ejson stringified string, found ${document}`
394+
`Expected provideTextDocumentContent to return json stringified string, found ${document}`
351395
);
352396
done();
353397
})

src/test/suite/editors/documentStringFixtures.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { EJSON } from 'bson';
1+
import { Binary, EJSON } from 'bson';
22

33
const docString =
44
'{"_id":{"$oid":"57e193d7a9cc81b4027498b5"},"Symbol":"symbol","String":"string","Int32":{"$numberInt":"42"},"Int64":{"$numberLong":"42"},"Double":{"$numberDouble":"-1"},"Binary":{"$binary":{"base64":"o0w498Or7cijeBSpkquNtg==","subType":"03"}},"BinaryUserDefined":{"$binary":{"base64":"AQIDBAU=","subType":"80"}},"Code":{"$code":"function() {}"},"CodeWithScope":{"$code":"function() {}","$scope":{}},"Subdocument":{"foo":"bar"},"Array":[{"$numberInt":"1"},{"$numberInt":"2"},{"$numberInt":"3"},{"$numberInt":"4"},{"$numberInt":"5"}],"Timestamp":{"$timestamp":{"t":42,"i":1}},"Regex":{"$regularExpression":{"pattern":"pattern","options":""}},"DatetimeEpoch":{"$date":{"$numberLong":"0"}},"DatetimePositive":{"$date":{"$numberLong":"2147483647"}},"DatetimeNegative":{"$date":{"$numberLong":"-2147483648"}},"True":true,"False":false,"DBPointer":{"$ref":"collection","$id":{"$oid":"57e193d7a9cc81b4027498b1"}},"DBRef":{"$ref":"collection","$id":{"$oid":"57fd71e96e32ab4225b723fb"},"$db":"database"},"Minkey":{"$minKey":1},"Maxkey":{"$maxKey":1},"Null":null,"Undefined":null}';
@@ -56,3 +56,12 @@ export const documentWithAllBsonTypesJsonified = `{
5656
"Null": null,
5757
"Undefined": null
5858
}`;
59+
60+
export const documentWithBinaryId = {
61+
_id: new Binary('aaa')
62+
};
63+
export const documentWithBinaryIdString = JSON.stringify(
64+
documentWithBinaryId,
65+
null,
66+
2
67+
);

0 commit comments

Comments
 (0)