Skip to main content
Version: Next

SQL Databases

QUBIQ connects to relational databases as a consumer — to read data onto screens, log values, run named queries, and store the audit journal. This is separate from the configuration database, which is internal and not user-accessible.

Supported drivers

DriverTypical portNotes
PostgreSQL5432Also covers Postgres-compatible engines.
MySQL3306MariaDB included.
SQL Server1433Windows and Linux hosts.
SQLiteFile-based; sandboxed, see below.

Configuration

FieldDescription
NameConnection identifier.
DriverOne of the above.
Host / PortServer address (not used for SQLite).
DatabaseDatabase or catalog name.
Username / PasswordCredentials. Encrypted at rest, never returned to the browser.
SSLRequire an encrypted connection.
Max connectionsPool ceiling. Sized to the database's limits, not to QUBIQ's demand.
AI username / passwordOptional read-only credential used by the AI assistant instead of the primary one.

SQLite specifics

FieldDescription
PathFile path, confined to the user-databases/ sandbox inside the data directory.
Create if missingCreate the file on first open.

SQLite paths are resolved through a sandbox at both create time and open time. Directory traversal, absolute paths outside the sandbox, and any attempt to open the internal configuration database are rejected; only .db, .sqlite and .sqlite3 extensions are permitted.

That is a security boundary, not a convenience limit: a user-defined connection must never be able to name an arbitrary file on the host.

Pooling and sizing

The pool is shared by everything that uses the connection — named queries, pipeline nodes, bound widgets, the AI assistant.

Size max connections against the database's limit and the number of QUBIQ services that will use it, not against your expected query rate. A pool larger than the server allows produces connection-refused errors under load; a pool of 5–20 is right for most deployments.

What you can do with a SQL connection

UseWhere
Bind a widget to query resultsQuery bindings
Run a saved, parameterised queryNamed queries
Read/write from a pipelineThe SQL Query node — Pipeline nodes
Read/write from a scriptsystem.db.*Scripting API
Store the security audit journalAudit journal

Named queries

A named query is a saved statement with declared parameters and its connection baked in. Prefer them over inline SQL:

  • The statement lives in one place; changing it does not mean editing every screen.
  • Parameters are bound, not concatenated — the injection surface disappears.
  • A screen or script refers to it by name, so it needs no database credentials of its own.
-- named query: production_by_shift
SELECT shift, SUM(units) AS units
FROM production
WHERE ts >= :start AND ts < :end
GROUP BY shift
ORDER BY shift

Called as system.db.runNamedQuery("production_by_shift", {start, end}) or bound directly to a table widget.

Stored procedures and transactions

CapabilityAPI
Call a procedure, receiving every result setsystem.db.callProc(...)
Managed transaction — auto-commit, auto-rollback on throwsystem.db.transaction(opts, fn)
Manual transaction handlesystem.db.transaction(opts)

Transactions accept an isolation level (ReadUncommittedSerializable, Snapshot), a readOnly flag and a server-side timeoutMs after which the transaction is rolled back automatically. That timeout matters: it means a browser disconnect cannot strand an open transaction holding locks.

For anything transactional, prefer a Gateway script, which runs entirely server-side. → Gateway scripts

Writing data

Two paths, with different guarantees:

PathGuarantee
Pipeline SQL nodeCovered by store-and-forward: buffered on outage, replayed in order, quarantined on permanent failure.
Script system.db.*Executes immediately; failure is returned to the caller to handle.

If a write must not be lost when the database is unavailable, put it in a pipeline.

Security

  • Give QUBIQ its own database account with the minimum rights it needs. A dashboard usually needs SELECT only.
  • Use the AI credential for a read-only account if you enable the assistant on a production database.
  • Prefer named queries to inline SQL. Where inline SQL is unavoidable, always use parameters.
  • Upstream errors are sanitised before they reach a client — QUBIQ does not leak the database's raw error text or schema detail to the browser.

Troubleshooting

SymptomCheck
Test fails with a timeoutFirewall or the server not listening on that interface.
Authentication fails but credentials are rightHost-based auth (pg_hba.conf), or the account is restricted by source host.
Works, then "too many connections" under loadPool larger than the server's limit; reduce max connections.
Queries slow only through QUBIQMissing index on the filter columns the binding adds; check the plan for the actual statement.
SQLite path rejectedOutside the sandbox, or a disallowed extension. Move the file under user-databases/.
TLS required by serverEnable SSL on the connection.

Next

MongoDB · QuestDB