All files / commands open-graph.ts

100% Statements 25/25
88.88% Branches 16/18
100% Functions 2/2
100% Lines 25/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86                1x   1x     7x 7x     7x               7x   7x                         7x   5x 5x 5x   5x 2x 2x   2x 1x         4x         4x   4x 3x         3x   1x       2x         2x 1x        
import * as vscode from 'vscode';
import { container } from 'tsyringe';
import { ServiceToken } from '@src/services/tokens';
import { ISparqlQueryService } from '@src/languages/sparql/services';
import { SparqlConnection } from '@src/languages/sparql/services/sparql-connection';
import { MENTOR_WORKSPACE_STORE } from '@src/languages/sparql/services/sparql-connection-service';
import { WorkspaceUri } from '@src/providers/workspace-uri';
 
const LARGE_GRAPH_THRESHOLD = 10000;
 
export const openGraph = {
	id: 'mentor.command.openGraph',
	handler: async (graphIri: vscode.Uri | string, connection?: SparqlConnection) => {
		const targetConnection = connection ?? MENTOR_WORKSPACE_STORE;
		const queryService = container.resolve<ISparqlQueryService>(ServiceToken.SparqlQueryService);
 
		// Hoisted so the catch block can offer it in the error notification.
		const constructQuery = `CONSTRUCT {
	?s ?p ?o .
} WHERE {
	GRAPH <${WorkspaceUri.toCanonicalString(graphIri)}> {
		?s ?p ?o .
	}
}`;
 
		try {
			// Check if the graph contains more than the threshold number of triples.
			const countQuery = `
				SELECT (COUNT(?s) as ?count)
				WHERE {
					SELECT ?s
					WHERE {
						GRAPH <${WorkspaceUri.toCanonicalString(graphIri)}> {
							?s ?p ?o .
						}
					}
					LIMIT ${LARGE_GRAPH_THRESHOLD}
				}
			`;
 
			const countResult = await queryService.executeQueryOnConnection(countQuery, targetConnection);
 
			Eif (countResult?.type === 'bindings' && countResult.bindings.length > 0) {
				const countValue = countResult.bindings[0].get('count');
				const count = countValue ? parseInt(countValue.value, 10) : 0;
 
				if (count === LARGE_GRAPH_THRESHOLD) {
					const message = `The graph contains more than ${LARGE_GRAPH_THRESHOLD.toLocaleString()} triples. Exporting it may take some time. Do you want to continue?`;
					const answer = await vscode.window.showWarningMessage(message, { modal: true }, 'Continue');
 
					if (answer !== 'Continue') {
						return;
					}
				}
			}
 
			await vscode.window.withProgress({
				location: vscode.ProgressLocation.Notification,
				title: 'Exporting graph...',
				cancellable: false
			}, async () => {
				const result = await queryService.executeQueryOnConnection(constructQuery, targetConnection);
 
				if (result?.type === 'quads' && result.data) {
					const document = await vscode.workspace.openTextDocument({
						content: result.data,
						language: 'turtle'
					});
 
					vscode.window.showTextDocument(document);
				} else {
					vscode.window.showInformationMessage('The graph is empty or could not be exported.');
				}
			});
		} catch (error: any) {
			const action = await vscode.window.showErrorMessage(
				`Failed to serialize graph: ${error.message}`,
				'Edit Query'
			);
 
			if (action === 'Edit Query') {
				await vscode.commands.executeCommand('mentor.command.openDocument', '', constructQuery);
			}
		}
	}
};