public override async ValueTask ExecuteAsync(int timeout, IDescriptorFiller descriptorFiller, CancellationToken cancellationToken = default) { EnsureNotDeallocated(); await descriptorFiller.FillAsync(_parameters, 0, cancellationToken).ConfigureAwait(false); ClearStatusVector(); NativeHelpers.CallIfExists(() => { _db.FbClient.fb_dsql_set_timeout(_statusVector, ref _handle, (uint)timeout); _db.ProcessStatusVector(_statusVector); }); ClearStatusVector(); var inSqlda = IntPtr.Zero; var outSqlda = IntPtr.Zero; if (_parameters != null) { inSqlda = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, _parameters); } if (StatementType == DbStatementType.StoredProcedure) { Fields.ResetValues(); outSqlda = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, _fields); } var trHandle = _transaction.HandlePtr; _db.FbClient.isc_dsql_execute2( _statusVector, ref trHandle, ref _handle, IscCodes.SQLDA_VERSION1, inSqlda, outSqlda); if (outSqlda != IntPtr.Zero) { var descriptor = XsqldaMarshaler.MarshalNativeToManaged(_db.Charset, outSqlda, true); var values = new DbValue[descriptor.Count]; for (var i = 0; i < values.Length; i++) { var d = descriptor[i]; var value = await d.DbValue.GetValueAsync(cancellationToken).ConfigureAwait(false); values[i] = new DbValue(this, d, value); } OutputParameters.Enqueue(values); } XsqldaMarshaler.CleanUpNativeData(ref inSqlda); XsqldaMarshaler.CleanUpNativeData(ref outSqlda); _db.ProcessStatusVector(_statusVector); if (DoRecordsAffected) { RecordsAffected = await GetRecordsAffectedAsync(cancellationToken).ConfigureAwait(false); } else { RecordsAffected = -1; } State = StatementState.Executed; }
public override async ValueTask <ExecuteResultItem[]> ExecuteAsync(int count, IDescriptorFiller descriptorFiller, CancellationToken cancellationToken = default) { var parametersData = new byte[count][]; for (var i = 0; i < parametersData.Length; i++) { await descriptorFiller.FillAsync(_statement.Parameters, i, cancellationToken).ConfigureAwait(false); // this may throw error, so it needs to be before any writing parametersData[i] = await _statement.WriteParametersAsync(cancellationToken).ConfigureAwait(false); } await Database.Xdr.WriteAsync(IscCodes.op_batch_create, cancellationToken).ConfigureAwait(false); await Database.Xdr.WriteAsync(_statement.Handle, cancellationToken).ConfigureAwait(false); // p_batch_statement var blr = _statement.Parameters.ToBlr(); await Database.Xdr.WriteBufferAsync(blr.Data, cancellationToken).ConfigureAwait(false); // p_batch_blr await Database.Xdr.WriteAsync(blr.Length, cancellationToken).ConfigureAwait(false); // p_batch_msglen var pb = new BatchParameterBuffer(); if (_statement.ReturnRecordsAffected) { pb.Append(IscCodes.Batch.TAG_RECORD_COUNTS, 1); } if (MultiError) { pb.Append(IscCodes.Batch.TAG_MULTIERROR, 1); } await Database.Xdr.WriteBufferAsync(pb.ToArray(), cancellationToken).ConfigureAwait(false); // p_batch_pb await Database.Xdr.WriteAsync(IscCodes.op_batch_msg, cancellationToken).ConfigureAwait(false); await Database.Xdr.WriteAsync(_statement.Handle, cancellationToken).ConfigureAwait(false); // p_batch_statement await Database.Xdr.WriteAsync(parametersData.Length, cancellationToken).ConfigureAwait(false); // p_batch_messages foreach (var item in parametersData) { await Database.Xdr.WriteOpaqueAsync(item, item.Length, cancellationToken).ConfigureAwait(false); // p_batch_data } await Database.Xdr.WriteAsync(IscCodes.op_batch_exec, cancellationToken).ConfigureAwait(false); await Database.Xdr.WriteAsync(_statement.Handle, cancellationToken).ConfigureAwait(false); // p_batch_statement await Database.Xdr.WriteAsync(_statement.Transaction.Handle, cancellationToken).ConfigureAwait(false); // p_batch_transaction; await Database.Xdr.FlushAsync(cancellationToken).ConfigureAwait(false); var numberOfResponses = 3; try { numberOfResponses--; var batchCreateResponse = await Database.ReadResponseAsync(cancellationToken).ConfigureAwait(false); numberOfResponses--; var batchMsgResponse = await Database.ReadResponseAsync(cancellationToken).ConfigureAwait(false); numberOfResponses--; var batchExecResponse = (BatchCompletionStateResponse)await Database.ReadResponseAsync(cancellationToken).ConfigureAwait(false); return(BuildResult(batchExecResponse)); } finally { await Database.SafeFinishFetchingAsync(numberOfResponses, cancellationToken).ConfigureAwait(false); } }