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
-
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> -
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.
-
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. -
getCacheMetrics(
) → Future< PreparedStatementMetrics?> - Returns prepared statement cache metrics from the worker.
-
getError(
) → Future< String> - Returns the last error message from the worker (plain text).
-
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. -
initialize(
) → Future< bool> - Initializes the worker isolate and ODBC environment.
-
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. -
poolHealthCheck(
int poolId) → Future< bool> -
Runs a health check on pool
poolId. -
poolReleaseConnection(
int connectionId) → Future< bool> -
Returns
connectionIdto its pool. -
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. -
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. -
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited