UNPKG

signalk-parquet

Version:

Vessel data Parquet file archive with automated value and geospatial triggers. History API compliant with cloud backups and queries.

73 lines 3.42 kB
"use strict"; /** * SQL fragment builders for federating the SQLite buffer into DuckDB queries. * * Per-path table architecture: each SignalK path has its own table in buffer.db. * Scalar tables have a `value` column; object tables have flattened `value_*` columns. * * Buffer rows reach DuckDB via a staged TEMP table (see buffer-staging.ts) rather * than an ATTACH of the live buffer.db — callers stage first and pass the staged * table name in. The WHERE clauses here re-apply the staging filters harmlessly * and add the per-request value/filter conditions. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.buildBufferScalarSubquery = buildBufferScalarSubquery; exports.buildBufferObjectSubquery = buildBufferObjectSubquery; const sql_escape_1 = require("./sql-escape"); const path_filters_1 = require("./path-filters"); /** * Build a buffer subquery for a scalar (numeric) path. * * Output columns: signalk_timestamp, value * Matches raw-tier parquet schema so it can be UNION ALL'd directly. * * When filters are provided, rows are restricted to matching column values. */ function buildBufferScalarSubquery(stagedTable, context, signalkPath, fromIso, toIso, filters) { const pathStr = String(signalkPath); // Root-level paths without dots are string properties (name, mmsi, uuid, etc.) const isStringPath = !pathStr.includes('.'); const valueExpr = isStringPath ? 'value' : 'TRY_CAST(value AS DOUBLE)'; return `(SELECT signalk_timestamp, ${valueExpr} AS value, NULL::VARCHAR AS value_json FROM ${stagedTable} WHERE context = '${(0, sql_escape_1.escapeSqlString)(String(context))}' AND signalk_timestamp >= '${(0, sql_escape_1.escapeSqlString)(fromIso)}' AND signalk_timestamp < '${(0, sql_escape_1.escapeSqlString)(toIso)}' AND exported = 0 AND value IS NOT NULL${(0, path_filters_1.buildBufferFilterClause)(filters)})`; } /** * Build a buffer subquery for an object path (e.g. navigation.position). * * Per-path tables already have flattened value_* columns, so no json_extract needed. * * When filters are provided, rows are restricted to matching column values. */ function buildBufferObjectSubquery(stagedTable, context, fromIso, toIso, components, bufferTableColumns, filters) { const componentSelects = Array.from(components.entries()) .map(([_name, comp]) => { // If we know the buffer table's columns, output NULL for missing ones if (bufferTableColumns && !bufferTableColumns.has(comp.columnName)) { return `NULL::DOUBLE AS ${comp.columnName}`; } // Columns are already flattened in per-path tables — just SELECT them directly if (comp.dataType === 'numeric') { return `TRY_CAST(${comp.columnName} AS DOUBLE) AS ${comp.columnName}`; } return `CAST(${comp.columnName} AS VARCHAR) AS ${comp.columnName}`; }) .join(',\n '); return `(SELECT signalk_timestamp, ${componentSelects} FROM ${stagedTable} WHERE context = '${(0, sql_escape_1.escapeSqlString)(String(context))}' AND signalk_timestamp >= '${(0, sql_escape_1.escapeSqlString)(fromIso)}' AND signalk_timestamp < '${(0, sql_escape_1.escapeSqlString)(toIso)}' AND exported = 0 AND value_json IS NOT NULL${(0, path_filters_1.buildBufferFilterClause)(filters)})`; } //# sourceMappingURL=buffer-sql-builder.js.map