AsyncNativeOdbcConnection class
Non-blocking wrapper around ODBC using a long-lived worker isolate.
Architecture: All FFI/ODBC operations run in a dedicated worker isolate. The main thread stays responsive; no blocking FFI calls run on the UI thread.
How it works
- initialize spawns a worker isolate and loads the ODBC driver.
- Each operation sends a request (via SendPort) to the worker.
- The worker runs the FFI call and sends back the result (via ReceivePort).
- The main thread never blocks on ODBC.
Performance
- Worker spawn (one-time): ~50–100 ms.
- Per-operation overhead: ~1–3 ms.
- Parallel queries: N queries complete in the time of the longest (not the sum).
Request timeout
Use requestTimeout to avoid UI hangs when the worker does not respond
(default 30s). Pass Duration.zero or null to disable.
Example
final async = AsyncNativeOdbcConnection(
requestTimeout: Duration(seconds: 30),
);
await async.initialize();
final connId = await async.connect(dsn);
final data = await async.executeQueryParams(connId, 'SELECT 1', []);
await async.disconnect(connId);
async.dispose(); // Pending requests complete with error
See also:
worker_isolate.dartfor the worker entry and request handling.- WorkerRequest and WorkerResponse for the message protocol.
Constructors
- AsyncNativeOdbcConnection({Duration? requestTimeout, void isolateEntry(SendPort)?, bool autoRecoverOnWorkerCrash = false})
Properties
- autoRecoverOnWorkerCrash → bool
-
When true, on worker isolate error/done
WorkerCrashRecovery.handleWorkerCrashis invoked after failing pending requests. All previous connection IDs are invalid after recovery; callers must reconnect.final - hashCode → int
-
The hash code for this object.
no setterinherited
- isInitialized → bool
-
Whether the worker isolate and ODBC environment are initialized.
no setter
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- workerIsolateForTesting → Isolate?
-
Worker isolate, exposed for testing (e.g., to simulate crash).
no setter
Methods
-
asyncCancel(
int asyncRequestId) → Future< bool> - Best-effort cancellation for async request.
-
asyncFree(
int asyncRequestId) → Future< bool> - Frees async request resources.
-
asyncGetResult(
int asyncRequestId, {int? maxBufferBytes}) → Future< Uint8List?> - Retrieves binary result for a completed async request.
-
asyncPoll(
int asyncRequestId) → Future< int> - Polls async request status.
-
beginTransaction(
int connectionId, int isolationLevel) → Future< int> -
Starts a transaction in the worker for
connectionIdwithisolationLevel. Returns the transaction ID on success. -
bulkInsertArray(
int connectionId, String table, List< String> columns, Uint8List dataBuffer, int rowCount) → Future<int> -
Performs bulk insert on
connectionId:table,columns,dataBuffer,rowCount. Returns rows inserted, or negative on error. -
bulkInsertParallel(
int poolId, String table, List< String> columns, Uint8List dataBuffer, int parallelism) → Future<int> -
Performs parallel bulk insert on
poolId. Returns rows inserted, or negative value on error. -
cancelStatement(
int stmtId) → Future< bool> -
Requests cancellation of prepared statement
stmtIdin the worker. -
catalogColumns(
int connectionId, String table) → Future< Uint8List?> -
Returns catalog columns for
tableonconnectionId. Binary result ornullon error. -
catalogTables(
int connectionId, {String catalog = '', String schema = ''}) → Future< Uint8List?> -
Returns catalog tables for
connectionId(optionalcatalogandschema). Returns binary result ornullon error. -
catalogTypeInfo(
int connectionId) → Future< Uint8List?> -
Returns type info for
connectionId. Binary result ornullon error. -
clearAllStatements(
) → Future< int> -
clearAuditEvents(
) → Future< bool> - Clears in-memory audit events in the worker.
-
clearMetadataCache(
) → Future< bool> - Clears metadata cache entries in the worker.
-
clearStatementCache(
) → Future< bool> - Clears the prepared statement cache in the worker.
-
closeStatement(
int stmtId) → Future< bool> -
Closes the prepared statement
stmtIdin the worker. -
commitTransaction(
int txnId) → Future< bool> -
Commits the transaction identified by
txnIdin the worker. -
connect(
String connectionString, {int timeoutMs = 0}) → Future< int> -
Opens a connection in the worker using
connectionString. -
createSavepoint(
int txnId, String name) → Future< bool> -
Creates a savepoint
namewithin the transactiontxnIdin the worker. -
detectDriver(
String connectionString) → Future< String?> - Detects the database driver from a connection string.
-
disconnect(
int connectionId) → Future< bool> -
Closes the connection identified by
connectionIdin the worker. -
dispose(
) → void - Shuts down the worker isolate and releases resources.
-
executeAsync(
int connectionId, String sql, {Duration pollInterval = const Duration(milliseconds: 10), Duration? timeout, int? maxBufferBytes}) → Future< Uint8List?> -
Executes
sqlin non-blocking mode using native async request lifecycle. -
executeAsyncStart(
int connectionId, String sql) → Future< int> - Starts non-blocking query execution in native layer.
-
executePrepared(
int stmtId, List< ParamValue> ? params, int timeoutOverrideMs, int fetchSize, {int? maxBufferBytes}) → Future<Uint8List?> -
Executes a prepared statement
stmtIdin the worker with optionalparams. Returns the binary result, ornullon error. -
executePreparedNamed(
int stmtId, Map< String, Object?> namedParams, int timeoutOverrideMs, int fetchSize, {int? maxBufferBytes}) → Future<Uint8List?> -
Executes a prepared statement
stmtIdusing named parameters. -
executeQueryMulti(
int connectionId, String sql, {int? maxBufferBytes}) → Future< Uint8List?> -
Executes
sqlonconnectionIdfor multi-result sets in the worker. WhenmaxBufferBytesis set, caps the result buffer size. Returns the binary result, ornullon error. -
executeQueryNamed(
int connectionId, String sql, Map< String, Object?> namedParams, {int? maxBufferBytes}) → Future<Uint8List?> -
Executes
sqlonconnectionIdusing named parameters. -
executeQueryParams(
int connectionId, String sql, List< ParamValue> params, {int? maxBufferBytes}) → Future<Uint8List?> -
Executes
sqlonconnectionIdwithparamsin the worker. -
getAuditEventsJson(
{int limit = 0}) → Future< String?> - Returns audit events as JSON payload, or null on failure.
-
getAuditStatusJson(
) → Future< String?> - Returns audit status as JSON payload, or null on failure.
-
getCacheMetrics(
) → Future< PreparedStatementMetrics?> - Returns prepared statement cache metrics from the worker.
-
getDriverCapabilitiesJson(
String connectionString) → Future< String?> - Returns driver capabilities payload as JSON, or null on failure.
-
getError(
) → Future< String> - Returns the last error message from the worker (plain text).
-
getMetadataCacheStatsJson(
) → Future< String?> - Returns metadata cache stats as JSON payload, or null on failure.
-
getMetrics(
) → Future< OdbcMetrics?> - Returns ODBC metrics from the worker (query count, errors, latency, etc.).
-
getStructuredError(
) → Future< StructuredError?> -
Returns the last structured error (message, SQLSTATE, native code), or
nullif there is no error. -
getVersion(
) → Future< Map< String, String> ?> - Returns engine version (api + abi) for compatibility checks.
-
initialize(
) → Future< bool> - Initializes the worker isolate and ODBC environment.
-
metadataCacheEnable(
{required int maxEntries, required int ttlSeconds}) → Future< bool> - Enables metadata cache in the worker.
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
poolClose(
int poolId) → Future< bool> -
Closes pool
poolIdin the worker. -
poolCreate(
String connectionString, int maxSize) → Future< int> - Creates a connection pool in the worker. Returns pool ID on success.
-
poolGetConnection(
int poolId) → Future< int> -
Obtains a connection from pool
poolId. Returns connection ID on success. -
poolGetState(
int poolId) → Future< ({int idle, int size})?> -
Returns the current state (size, idle) of pool
poolId, ornullon error. -
poolGetStateJson(
int poolId) → Future< String?> - Returns detailed pool state payload as JSON, or null on failure.
-
poolHealthCheck(
int poolId) → Future< bool> -
Runs a health check on pool
poolId. -
poolReleaseConnection(
int connectionId) → Future< bool> -
Returns
connectionIdto its pool. -
poolSetSize(
int poolId, int newMaxSize) → Future< bool> -
Resizes pool
poolIdtonewMaxSizein the worker. -
prepare(
int connectionId, String sql, {int timeoutMs = 0}) → Future< int> -
Prepares
sqlonconnectionIdin the worker. -
prepareNamed(
int connectionId, String sql, {int timeoutMs = 0}) → Future< int> -
Prepares
sqlwith named parameters onconnectionIdin the worker. -
recoverWorker(
) → Future< void> - Disposes the current worker and re-initializes a fresh one.
-
releaseSavepoint(
int txnId, String name) → Future< bool> -
Releases savepoint
namein transactiontxnId. Transaction stays active. -
rollbackToSavepoint(
int txnId, String name) → Future< bool> -
Rolls back to savepoint
namein transactiontxnId. Transaction stays active. -
rollbackTransaction(
int txnId) → Future< bool> -
Rolls back the transaction identified by
txnIdin the worker. -
setAuditEnabled(
{required bool enabled}) → Future< bool> - Enables/disables native audit event collection in the worker.
-
streamAsync(
int connectionId, String sql, {int fetchSize = 1000, int chunkSize = 64 * 1024, Duration pollInterval = const Duration(milliseconds: 10), int? maxBufferBytes}) → Stream< ParsedRowBuffer> -
Runs
sqlusing native async stream lifecycle:stream_start_async -> stream_poll_async -> stream_fetch -> stream_close. -
streamCancel(
int streamId) → Future< bool> - Cancels an active low-level native stream in the worker.
-
streamPollAsync(
int streamId) → Future< int> - Polls low-level async stream status.
-
streamQuery(
int connectionId, String sql, {int chunkSize = 1000, int? maxBufferBytes}) → Stream< ParsedRowBuffer> -
Runs
sqlin the worker using native streaming. -
streamQueryBatched(
int connectionId, String sql, {int fetchSize = 1000, int chunkSize = 64 * 1024, int? maxBufferBytes}) → Stream< ParsedRowBuffer> -
Runs
sqlin the worker using native batched streaming. -
streamStartAsync(
int connectionId, String sql, {int fetchSize = 1000, int chunkSize = 64 * 1024}) → Future< int> - Starts low-level async stream lifecycle and returns stream ID.
-
toString(
) → String -
A string representation of this object.
inherited
-
validateConnectionString(
String connectionString) → Future< String?> - Validates connection string format without opening a connection.
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited