openCursor method

Future<FbQuery> openCursor({
  1. required String sql,
  2. List parameters = const [],
  3. bool inlineBlobs = true,
  4. FbTransaction? inTransaction,
})

Executes an SQL statement, which returns a data set and requires allocation of a database cursor.

This method should be used for executing SELECT statements, or EXECUTE BLOCK which returns a set of rows (i.e. contains SUSPEND statements). openCursor allocates a database cursor, so after execution of the SQL statement, you can use methods allowing access to the result set (like rows, fetchOneAsMap, etc.). sql must be a valid SQL statement, which can optionally contain sql must be a valid SQL statement, which can optionally contain ? (question mark) placeholders for value parameters (the placeholders can't parametrize database objects, like table or column names, only the actual values placed in the statement). For each ? placeholder, a corresponding value should be passed in the parameters list (the type must correspond to the expected value type implied by the context in which the placeholder appears in the statement). The inlineBlobs parameter allows you to specify the way blob columns are to be treated. If inlineBlobs is true, all blob columns will be returned inside data rows as ByteBuffer objects. Otherwise, only the blob IDs will be present in the row data and to access the actual blob binary data you need to use FbDb.openBlob or FbDb.blobToFile.

Example:

await q.openCursor(
  sql: "select * from DEPARTMENT "
       "where DEPT_NO = ?",
  parameters: ["180"], // a single string parameter
);
await for (var row in q.rows()) {
  // process the row (which is a dictionary)
}
await q.close();

Implementation

Future<FbQuery> openCursor({
  required String sql,
  List<dynamic> parameters = const [],
  bool inlineBlobs = true,
  FbTransaction? inTransaction,
}) async {
  if (_db == null) {
    throw FbClientException("No active database connection");
  }
  await close(); // close the previously associated worker, if any
  final msg = await _db?._askWorker(FbDbControlOp.queryOpen, [
    sql,
    parameters,
    inlineBlobs,
    if (inTransaction != null) inTransaction.handle,
  ]);
  _throwIfErrorResponse(msg);
  final r = msg as FbDbResponse;
  if (r.data.isEmpty) {
    throw FbClientException(
      "FbQuery: connection worker did not provide "
      "a send port for the query",
    );
  }
  _toWorker = r.data[0];
  _db?._activeQueries[hashCode] = this;
  return this;
}