LCOV - code coverage report
Current view: top level - dashql-app/src/shell - shell_script.ts Coverage Total Hit
Test: DashQL 6e74948 Lines: 100.0 % 44 44
Test Date: 2026-11-06 17:46:50

            Line data    Source code
       1              : import type * as dashql from '@ankoh/dashql-core';
       2              : 
       3            1 : function terminateStatement(text: string): string {
       4            1 :     return text.endsWith(';') ? text : `${text};`;
       5            1 : }
       6              : 
       7              : /// Split SQL into its statements, keeping SQL that does not parse as a single statement
       8            1 : function splitSql(core: dashql.DashQL, catalog: dashql.DashQLCatalog, sql: string, out: string[]) {
       9            1 :     const trimmed = sql.trim();
      10            1 :     if (trimmed.length === 0) return;
      11              : 
      12            1 :     const bytes = new TextEncoder().encode(sql);
      13            1 :     const decoder = new TextDecoder();
      14            1 :     const script = core.createScript(catalog);
      15            1 :     let parsed: dashql.FlatBufferPtr<dashql.buffers.parser.ParsedScript> | null = null;
      16            1 :     try {
      17            1 :         script.replaceText(sql);
      18            1 :         script.parse();
      19            1 :         parsed = script.getParsed();
      20            1 :         const reader = parsed.read();
      21            1 :         if (reader.scannerErrorsLength() > 0 || reader.parserErrorsLength() > 0 || reader.statementsLength() === 0) {
      22            1 :             out.push(terminateStatement(trimmed));
      23            1 :             return;
      24            1 :         }
      25            1 :         for (let i = 0; i < reader.statementsLength(); ++i) {
      26            1 :             const span = reader.statements(i)!.statementSpan();
      27            1 :             if (!span) continue;
      28            1 :             const text = decoder.decode(bytes.subarray(span.offset(), span.offset() + span.length())).trim();
      29            1 :             if (text.length > 0) out.push(terminateStatement(text));
      30            1 :         }
      31            1 :     } finally {
      32            1 :         script.destroy();
      33            1 :     }
      34            1 : }
      35              : 
      36              : /// Split a script into the prompts the shell offers one after another, e.g. a shared script or a snippet.
      37              : /// Lines starting with a dot are shell commands, everything between them is SQL.
      38            1 : export function splitShellScript(core: dashql.DashQL, catalog: dashql.DashQLCatalog, script: string): string[] {
      39            1 :     const out: string[] = [];
      40            1 :     let sql: string[] = [];
      41            1 :     for (const line of script.split(/\r?\n/)) {
      42            1 :         const trimmed = line.trim();
      43            1 :         if (trimmed.startsWith('.')) {
      44            1 :             splitSql(core, catalog, sql.join('\n'), out);
      45            1 :             sql = [];
      46            1 :             out.push(trimmed);
      47            1 :         } else {
      48            1 :             sql.push(line);
      49              :         }
      50            1 :     }
      51            1 :     splitSql(core, catalog, sql.join('\n'), out);
      52            1 :     return out;
      53            1 : }
        

Generated by: LCOV version 2.0-1