prepare static method

Future<OracleStatement> prepare({
  1. required DpiOracle dpiOracle,
  2. required Pointer<dpiConn> connection,
  3. required Pointer<dpiContext> context,
  4. required String sql,
  5. bool scrollable = false,
})

Prepare a SQL statement without executing it

Implementation

static Future<OracleStatement> prepare({
  required DpiOracle dpiOracle,
  required Pointer<dpiConn> connection,
  required Pointer<dpiContext> context,
  required String sql,
  bool scrollable = false,
}) async {
  final memoryManager = MemoryManager();

  try {
    // Allocate memory for statement
    final statementPtr = memoryManager.allocate<Pointer<dpiStmt>>(sizeOf<Pointer<dpiStmt>>());
    final errorInfo = memoryManager.allocate<dpiErrorInfo>(sizeOf<dpiErrorInfo>());

    // Convert SQL to native
    final sqlNative = StringUtils.toNativeUtf8(sql, memoryManager);

    // Prepare statement
    var result = dpiOracle.dpiConn_prepareStmt(
      connection,
      scrollable ? 1 : 0,
      sqlNative,
      StringUtils.getUtf8ByteLength(sql),
      nullptr,
      0,
      statementPtr,
    );

    if (result == DPI_FAILURE) {
      dpiOracle.dpiContext_getError(context, errorInfo);
      final errorMsg = StringUtils.fromNativeUtf8(errorInfo.ref.message.cast<Char>());
      final errorCode = errorInfo.ref.code;

      throw OracleStatementException(
        'Failed to prepare statement',
        errorCode: errorCode,
        errorMessage: errorMsg,
        sql: sql,
      );
    }

    return OracleStatement._(
      dpiOracle,
      connection,
      context,
      statementPtr,
      sql,
      memoryManager,
    );
  } catch (e) {
    memoryManager.dispose();
    if (e is OracleException) {
      rethrow;
    }
    throw OracleStatementException('Statement preparation failed: $e', sql: sql);
  }
}