id: uuid()

in gui/extension/src/DocumentCommandHandler.ts [748:1159]


                                    id: uuid(),
                                    language: this.languageFromConnection(connection),
                                    caption: "Selected SQL",
                                    content: sql,
                                });
                            }
                        }
                    });
                }
            }));

        context.subscriptions.push(commands.registerCommand("msg.closeEditor", (
            entry?: IOdmNotebookEntry | IOdmScriptEntry) => {
            if (entry?.parent) {
                const provider = entry.parent.parent?.provider;
                const connection = entry.parent;
                if (provider instanceof DBConnectionViewProvider) {
                    void provider.closeEditor(connection.details.id, entry.id, entry.parent.id);
                }
            }
        }));

        context.subscriptions.push(commands.registerCommand("msg.newNotebookMysql",
            (entry?: IOdmConnectionPageEntry) => {
                void this.createNewEditor({ entry, language: "msg" });
            }));

        context.subscriptions.push(commands.registerCommand("msg.newNotebookSqlite",
            (entry?: IOdmConnectionPageEntry) => {
                void this.createNewEditor({ entry, language: "msg" });
            }));

        context.subscriptions.push(commands.registerCommand("msg.newScriptJs", (entry?: IOdmConnectionPageEntry) => {
            void this.createNewEditor({ entry, language: "javascript" });
        }));

        context.subscriptions.push(commands.registerCommand("msg.newScriptMysql", (entry?: IOdmConnectionPageEntry) => {
            void this.createNewEditor({ entry, language: "mysql" });
        }));

        context.subscriptions.push(commands.registerCommand("msg.newScriptSqlite",
            (entry?: IOdmConnectionPageEntry) => {
                void this.createNewEditor({ entry, language: "sql" });
            }));

        context.subscriptions.push(commands.registerCommand("msg.newScriptTs", (entry?: IOdmConnectionPageEntry) => {
            void this.createNewEditor({ entry, language: "typescript" });
        }));

        context.subscriptions.push(commands.registerCommand("msg.mrs.addDbObject", (
            entry?: ICdmTableEntry | ICdmViewEntry | ICdmRoutineEntry) => {
            if (entry) {
                const connection = entry.parent.parent.parent;
                if (entry.type === CdmEntityType.Table || entry.type === CdmEntityType.View
                    || entry.type === CdmEntityType.StoredFunction || entry.type === CdmEntityType.StoredProcedure) {
                    // First, create a new temporary dbObject, then call the DbObject dialog
                    this.createNewDbObject(connection.backend, entry).then((dbObject) => {
                        const provider = this.#host.currentProvider;
                        void provider?.editMrsDbObject(connection.details.id,
                            { dbObject, createObject: true });
                    }).catch((reason) => {
                        void ui.showErrorMessage(`${String(reason)}`, {});
                    });
                } else {
                    void ui.showErrorMessage(`The database object type '${entry.caption}' is not supported at ` +
                        `this time`, {});
                }
            }
        }));

        context.subscriptions.push(commands.registerCommand("msg.mrs.editDbObject", (entry?: ICdmRestDbObjectEntry) => {
            if (entry) {
                const provider = this.#host.currentProvider;
                const connection = entry.parent.parent.parent.parent;
                void provider?.editMrsDbObject(connection.details.id,
                    { dbObject: entry.details, createObject: false });
            }
        }));

        context.subscriptions.push(commands.registerCommand("msg.newSession", () => {
            const provider = this.#host.currentProvider;
            void provider?.openSession({ sessionId: uuid() });
        }));

        context.subscriptions.push(commands.registerCommand("msg.openSession", (details: IShellSessionDetails) => {
            const provider = this.#host.currentProvider;
            void provider?.openSession(details);
        }));

        context.subscriptions.push(commands.registerCommand("msg.newSessionUsingConnection",
            (entry: ICdmConnectionEntry | IOdmConnectionPageEntry) => {
                const provider = this.#host.currentProvider;

                const caption = entry.type === CdmEntityType.Connection ? entry.details.caption : entry.caption;
                const dbConnectionId = entry.details.id;

                const details: IShellSessionDetails = {
                    sessionId: uuid(),
                    caption,
                    dbConnectionId,
                };
                void provider?.openSession(details);
            }));

        context.subscriptions.push(commands.registerCommand("msg.removeSession", (entry: IOdmShellSessionEntry) => {
            const provider = entry.parent?.parent?.provider;
            if (provider instanceof DBConnectionViewProvider) {
                void provider.removeSession(entry.details);
            }
        }));
    }

    public async addNewSqlScript(connectionId: number, command: string, schemaName: string,
        scriptName: string, placeHolder: string): Promise<void> {

        let name: string | undefined = "";
        let sql = "";
        // If the commands is a create command, get the name of the new routine
        if (command.startsWith("msg.create")) {
            name = await window.showInputBox({
                title: `New Routine on Schema \`${schemaName}\``,
                placeHolder,
                prompt: "Please enter a name for the new routine:",
                value: "",
            });

            if (name === undefined) {
                return;
            }
            if (name === "") {
                name = placeHolder;
            }
        }

        switch (command) {
            case "msg.createProcedure": {
                sql = `DELIMITER %%\nDROP PROCEDURE IF EXISTS \`${schemaName}\`.\`${name}\`%%\n`
                    + `/* Add or remove procedure IN/OUT/INOUT parameters as needed. */\n`
                    + `CREATE PROCEDURE \`${schemaName}\`.\`${name}\`(IN arg1 INTEGER, OUT arg2 INTEGER)\n`
                    + `SQL SECURITY DEFINER\nNOT DETERMINISTIC\nBEGIN\n`
                    + `    /* Insert the procedure code here. */\n    SET arg2 = arg1 * 2;\n`
                    + `END%%\nDELIMITER ;\n\n`
                    + `CALL \`${schemaName}\`.\`${name}\`(1, @arg2);\nSELECT @arg2;`;
                break;
            }

            case "msg.createFunction": {
                sql = `DELIMITER %%\nDROP FUNCTION IF EXISTS \`${schemaName}\`.\`${name}\`%%\n`
                    + `/* Add or remove function parameters as needed. */\n`
                    + `CREATE FUNCTION \`${schemaName}\`.\`${name}\`(arg1 INTEGER)\nRETURNS INTEGER\n`
                    + `SQL SECURITY DEFINER\nDETERMINISTIC\nBEGIN\n`
                    + `    /* Insert the function code here. */\n    return arg1;\nEND%%\nDELIMITER ;`
                    + `\n\nSELECT \`${schemaName}\`.\`${name}\`(1);`;
                break;
            }

            case "msg.createFunctionJs": {
                sql = `DROP FUNCTION IF EXISTS \`${schemaName}\`.\`${name}\`;\n`
                    + `/* Add or remove function parameters as needed. */\n`
                    + `CREATE FUNCTION \`${schemaName}\`.\`${name}\`(arg1 INTEGER)\n`
                    + `RETURNS INTEGER\n`
                    + `SQL SECURITY DEFINER\n`
                    + `DETERMINISTIC LANGUAGE JAVASCRIPT\nAS $$\n`
                    + `    /* Insert the function code here. */\n`
                    + `    console.log("Hello World!");\n`
                    + `    console.log('{"info": "This is Javascript"}');\n`
                    + `    /* throw("Custom Error"); */\n`
                    + `    return arg1;\n`
                    + `$$;\n`
                    + `SELECT \`${schemaName}\`.\`${name}\`(1);`;
                break;
            }

            case "msg.createProcedureJs": {
                sql = `DROP PROCEDURE IF EXISTS \`${schemaName}\`.\`${name}\`;\n`
                    + `/* Add or remove procedure parameters as needed. */\n`
                    + `CREATE PROCEDURE \`${schemaName}\`.\`${name}\`(IN arg1 INTEGER, OUT arg2 INTEGER)\n`
                    + `DETERMINISTIC LANGUAGE JAVASCRIPT\nAS $$\n`
                    + `    /* Insert the procedure code here. */\n`
                    + `    console.log("Hello World!");\n`
                    + `    const sql_query = session.prepare('SELECT ?');\n`
                    + `    const query_result = sql_query.bind(arg1).execute().fetchOne();\n`
                    + `    arg2 = query_result[0];\n`
                    + `$$;\n`
                    + `CALL\`${schemaName}\`.\`${name}\`(42, @out);\n`
                    + `SELECT @out;`;
                break;
            }

            case "msg.editRoutine": {
                sql = placeHolder;
                break;
            }

            default:
        }

        const provider = this.#host.currentProvider ?? this.#host.newProvider;
        if (provider) {
            this.createNewScriptEditor(
                provider, scriptName, sql, "mysql", connectionId,
            );
        }
    }

    /**
     * Triggered on authentication, which means existing connections are no longer valid.
     */
    public async refreshConnectionTree(): Promise<void> {
        await this.#connectionsProvider.closeAllConnections();
        this.#connectionsProvider.refresh();
    }

    public clear(): void {
        this.#openEditorsTreeDataProvider.clear();
    }

    /**
     * Called when a new DB tree provider is opened (a new web app tab).
     *
     * @param provider The provider that was opened.
     */
    public providerOpened(provider: DBConnectionViewProvider): void {
        // Register the new provider with our data model.
        this.#openDocumentsModel.openProvider(provider);
        this.#openEditorsTreeDataProvider.refresh();
    }

    public providerClosed(provider: DBConnectionViewProvider): void {
        this.#openDocumentsModel.closeProvider(provider);
        this.#openScripts.delete(provider);
        this.#openEditorsTreeDataProvider.refresh();
        if (this.#openEditorsTreeDataProvider.clear(provider)) {
            // No provider remained open. Reset the current schemas.
            this.#connectionsProvider.resetCurrentSchemas();
        }
    }

    /**
     * Helper to create a unique caption for a new provider.
     *
     * @returns The new caption.
     */
    public generateNewProviderCaption(): string {
        return this.#openDocumentsModel.createUniqueCaption();
    }

    public providerStateChanged(provider: DBConnectionViewProvider, active: boolean): void {
        this.#connectionsProvider.providerStateChanged(provider, active);
    }

    private createNewDbObject = async (backend: ShellInterfaceSqlEditor,
        entry: ICdmTableEntry | ICdmViewEntry | ICdmRoutineEntry): Promise<IMrsDbObjectData> => {

        const dbObject: IMrsDbObjectData = {
            comments: "",
            crudOperations: (entry.type === CdmEntityType.StoredProcedure) ? ["UPDATE"] : ["READ"],
            crudOperationFormat: "FEED",
            dbSchemaId: "",
            enabled: 1,
            id: "",
            name: entry.caption,
            objectType: DocumentCommandHandler.#dmTypeToMrsType.get(entry.type)!,
            requestPath: `/${convertSnakeToCamelCase(entry.caption)}`,
            requiresAuth: 1,
            rowUserOwnershipEnforced: 0,
            serviceId: "",
            autoDetectMediaType: 0,
        };

        const services = await backend.mrs.listServices();
        let service;
        if (services.length === 1) {
            service = services[0];
        } else if (services.length > 1) {
            // Lookup default service
            service = services.find((service) => {
                return service.isCurrent;
            });

            if (!service) {
                // No default connection set. Show a picker.
                const items = services.map((s) => {
                    return s.urlContextRoot;
                });

                const name = await window.showQuickPick(items, {
                    title: "Select a connection for SQL execution",
                    matchOnDescription: true,
                    placeHolder: "Type the name of an existing DB connection",
                });

                if (name) {
                    service = services.find((candidate) => {
                        return candidate.urlContextRoot === name;
                    });
                }

            }
        }

        if (service) {
            const schemas = await backend.mrs.listSchemas(service.id);
            const schema = schemas.find((schema) => {
                return schema.name === entry.schema;
            });

            // Check if the DbObject's schema is already exposed as an MRS schema
            dbObject.schemaName = entry.schema;
            if (schema) {
                dbObject.dbSchemaId = schema.id;
            } else {
                const answer = await ui.showInformationMessage(
                    `The database schema ${entry.schema} has not been added to the REST Service. Do you want to add ` +
                    "the schema now?", {}, "Yes", "No");
                if (answer === "Yes") {
                    dbObject.dbSchemaId = await backend.mrs.addSchema(service.id, entry.schema, 1,
                        `/${convertSnakeToCamelCase(entry.schema)}`, false, null, null, undefined);

                    void commands.executeCommand("msg.refreshConnections");
                    showMessageWithTimeout(`The MRS schema ${entry.schema} has been added successfully.`, 5000);
                } else {
                    throw new Error("Operation cancelled.");
                }
            }
        } else {
            if (services.length === 0) {
                throw new Error("Please create a REST Service before adding DB Objects.");
            } else {
                throw new Error("No REST Service selected.");
            }
        }

        return dbObject;
    };

    private connectedToUrl = (url?: URL): Promise<boolean> => {
        this.#isConnected = url !== undefined;

        if (this.#displayDbConnectionOverviewWhenConnected) {
            this.#displayDbConnectionOverviewWhenConnected = false;
            void commands.executeCommand("msg.openDBBrowser");
        }

        return Promise.resolve(true);
    };

    /**
     * Triggered from CodeBlocks when an embedded query must be executed.
     *
     * @param details The request to send to the app.
     *
     * @returns A promise returning a flag whether the task was successfully executed or not.
     */
    private executeCodeBlock = (details: ICodeBlockExecutionOptions): Promise<boolean> => {
        const provider = this.#host.currentProvider;
        if (provider) {
            return provider.runCode(details.connectionId, {
                linkId: details.linkId,
                code: details.query,
                language: "mysql",
            });
        }

        return Promise.resolve(false);
    };

    private editorLoadScript = (details: IScriptRequest): Promise<boolean> => {
        // The user has to select a target file.
        const filters: { [key: string]: string[]; } = {};

        switch (details.language) {
            case "mysql": {
                filters.SQL = ["mysql", "sql"];
                break;
            }

            case "sql": {
                filters.SQL = ["sql"];
                break;
            }

            case "typescript": {
                filters.TypeScript = ["ts"];
                break;
            }

            case "javascript": {
                filters.JavaScript = ["js"];
                break;
            }

            default:
        }

        void window.showOpenDialog({
            title: "Load Script File",
            filters,
            canSelectFiles: true,
            canSelectFolders: false,
            canSelectMany: false,
        }).then((list: Uri[]) => {
            if (list.length > 0) {
                void workspace.fs.readFile(list[0]).then((content) => {
                    const provider = this.#host.currentProvider;
                    if (provider) {
                        const scripts = this.#openScripts.get(provider);
                        if (scripts) {
                            scripts.set(details.id, list[0]);
                            const newName = basename(list[0].fsPath);

                            void provider.renameFile({