Skip to content

feat(plugin-influxdb): add an InfluxDB 2 and 3 driver over HTTP - #3976

Merged
datlechin merged 7 commits into
TableProApp:mainfrom
J2TeamNNL:feat/influxdb-driver
Nov 1, 2026
Merged

datlechin merged 7 commits into
TableProApp:mainfrom
J2TeamNNL:feat/influxdb-driver

Conversation

@J2TeamNNL

@J2TeamNNL J2TeamNNL commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • New registry plugin InfluxDBDriverPlugin for InfluxDB 2.x and 3.x over HTTP, no new dependency.
  • TableProInfluxDBCore holds the socket-free logic: routing, the Flux reading, requests, decoders, grid statements and the catalog. The app links it too, so Safe Mode and the driver route a statement by one rule.
  • The version comes from X-Influxdb-Version, else the 3.x /ping body. A 1.x server is refused at connect.
  • 3.x runs SQL and InfluxQL through /api/v3; 2.x runs Flux through /api/v2/query and InfluxQL through /query.
  • On 2.x, InfluxQL reaches a bucket through its DBRP mapping (db + rp), so a telegraf/weekly bucket or a made mapping reads correctly.
  • Connect checks the token within the connect timeout: /ping on 3.x, one bucket on 2.x. The health ping is the same single request.
  • A first line -- sql, -- influxql or // flux (either comment style) picks the language and is blanked before sending. Unmarked text is guessed; the grid's own statements carry the marker.
  • Typed InfluxQL with a ; anywhere but its end is refused, since 2.x /query runs every statement it gets.
  • On 2.x the driver has the server parse a Flux script (/api/v2/query/ast) before running it, and refuses one the server reads as writing or reaching outside where the gate's reading did not.
  • Form bodies and URL queries percent-encode everything outside RFC 3986's unreserved set. A raw ; made 2.x drop q and answer {}.
  • The grid is read-only: measurements are external tables, no column is a key, generateRowWrites refuses every change, and InfluxDB is in SQLDDLFallbackPolicy.
  • Grid results are typed from the measurement's schema and filter literals follow it, so a tag holding 1 is quoted and a float is not. The schema is read again when a filter names a column it lacks.
  • Grid statements are rendered by the driver and escaped per code point; InfluxQL regex bodies are printable ASCII with /, \, controls and non-ASCII as hex escapes, so a filter value cannot end the literal or add a statement.
  • InfluxQL IS NULL works on tags only; on a field, and for a regex or IS EMPTY on a number, the filter is refused instead of matching nothing.
  • 3.x empty pages keep their columns. SQL with no database chosen asks for one; SHOW DATABASES runs without.
  • Safe Mode reads each statement as the driver receives it. A Flux script reads only when every import is on a read-only list and it names no to or wideTo; any other import (http, sql, experimental/influxdb, monitor, secrets, notification packages) writes and reaches outside, and so does a package used as a value. A host or file argument, plain, quoted or shorthand, reaches outside. The Flux lexer knows multi-line regexes, ${} interpolation, durations and pkg["member"], and an unclosed literal fails closed.
  • A Flux or InfluxQL write refreshes the sidebar (CatalogChangeClassifier).
  • Lexical profile for InfluxDB: backslash escapes in both quotes and // comments, ANSI as the alternative reading.
  • CSV is read as bytes; one cell with bad UTF-8 no longer empties the grid. Decoders map columns once per header.
  • The connection creates each task under the lock close() invalidates with, and refuses redirects through PluginRedirectRefusingDelegate.

Test plan

  • swift test --filter TableProInfluxDBCoreTests: 126 tests, including the server's AST for nine scripts.
  • SQLLexicalReadingsTests (InfluxDB profile), and the hosted QueryClassifierFluxTests, CatalogChangeClassifierTests, every QueryClassifier* suite and the MCP statement gate suites: 290 pass.
  • scripts/probes/check-influxdb.sh against influxdb:2 (v2.9.1) and two influxdb:3-core (3.12.2) servers: 115 checks pass, including the refused ; statement, a grid filter that tried to DROP a scratch measurement, a Flux write hidden from the lexer, and a read-only token running Flux. The earlier driver fails it on the external-table type, the key column, schema typing, empty-page columns and the // influxql marker.
  • verify.sh build, lint on every changed Swift file, localization.py plugins and extracted. verify.sh plugins built the InfluxDB plugin; the run stopped at DamengDriver, whose native bridge this Mac lacks.

Docs: TableProApp/docs#153, to merge after this one.

Fixes #2477

SQL and InfluxQL on 3.x, Flux and InfluxQL on 2.x, chosen from the server version and the statement. Read-only grid with filters, paging and counts. Flux is tiered for Safe Mode.
# Conflicts:
#	apple/TablePro/Core/Plugins/PluginMetadataRegistry+RegistryDefaults.swift
#	apple/TablePro/Models/Connection/DatabaseType.swift
#	apple/TablePro/Resources/Localizable.xcstrings
#	apple/TableProTests/Core/Plugins/PluginMetadataRegistryTypeCountTests.swift
@datlechin
datlechin disabled auto-merge November 1, 2026 15:07
@datlechin
datlechin enabled auto-merge (squash) November 1, 2026 15:58
@datlechin
datlechin merged commit 579ce4a into TableProApp:main Nov 1, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

InfluxDB driver

2 participants