Skip to content

Commit 1cc2ed0

Browse files
committed
Property BatchBufferSize and refactoring along the way.
1 parent 92499bc commit 1cc2ed0

File tree

9 files changed

+182
-137
lines changed

9 files changed

+182
-137
lines changed

src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsStatement.cs

Lines changed: 59 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -764,9 +764,8 @@ protected ValueTask ProcessAllocateResponseAsync(GenericResponse response, Cance
764764
#region op_execute/op_execute2 methods
765765
protected virtual void SendExecuteToBuffer(int timeout, IDescriptorFiller descriptorFiller)
766766
{
767-
descriptorFiller.Fill(_parameters, 0);
768767
// this may throw error, so it needs to be before any writing
769-
var parametersData = WriteParameters();
768+
var parametersData = GetParameterData(descriptorFiller, 0);
770769

771770
if (StatementType == DbStatementType.StoredProcedure)
772771
{
@@ -802,9 +801,8 @@ protected virtual void SendExecuteToBuffer(int timeout, IDescriptorFiller descri
802801
}
803802
protected virtual async ValueTask SendExecuteToBufferAsync(int timeout, IDescriptorFiller descriptorFiller, CancellationToken cancellationToken = default)
804803
{
805-
await descriptorFiller.FillAsync(_parameters, 0, cancellationToken).ConfigureAwait(false);
806804
// this may throw error, so it needs to be before any writing
807-
var parametersData = await WriteParametersAsync(cancellationToken).ConfigureAwait(false);
805+
var parametersData = await GetParameterDataAsync(descriptorFiller, 0, cancellationToken).ConfigureAwait(false);
808806

809807
if (StatementType == DbStatementType.StoredProcedure)
810808
{
@@ -1172,6 +1170,57 @@ protected async ValueTask<Descriptor[]> ParseTruncSqlInfoAsync(byte[] info, byte
11721170
return rowDescs;
11731171
}
11741172

1173+
protected virtual byte[] WriteParameters()
1174+
{
1175+
if (_parameters == null)
1176+
return null;
1177+
1178+
using (var ms = new MemoryStream())
1179+
{
1180+
var xdr = new XdrReaderWriter(new DataProviderStreamWrapper(ms), _database.Charset);
1181+
for (var i = 0; i < _parameters.Count; i++)
1182+
{
1183+
var field = _parameters[i];
1184+
try
1185+
{
1186+
WriteRawParameter(xdr, field);
1187+
xdr.Write(field.NullFlag);
1188+
}
1189+
catch (IOException ex)
1190+
{
1191+
throw IscException.ForIOException(ex);
1192+
}
1193+
}
1194+
xdr.Flush();
1195+
return ms.ToArray();
1196+
}
1197+
}
1198+
protected virtual async ValueTask<byte[]> WriteParametersAsync(CancellationToken cancellationToken = default)
1199+
{
1200+
if (_parameters == null)
1201+
return null;
1202+
1203+
using (var ms = new MemoryStream())
1204+
{
1205+
var xdr = new XdrReaderWriter(new DataProviderStreamWrapper(ms), _database.Charset);
1206+
for (var i = 0; i < _parameters.Count; i++)
1207+
{
1208+
var field = _parameters[i];
1209+
try
1210+
{
1211+
await WriteRawParameterAsync(xdr, field, cancellationToken).ConfigureAwait(false);
1212+
await xdr.WriteAsync(field.NullFlag, cancellationToken).ConfigureAwait(false);
1213+
}
1214+
catch (IOException ex)
1215+
{
1216+
throw IscException.ForIOException(ex);
1217+
}
1218+
}
1219+
await xdr.FlushAsync(cancellationToken).ConfigureAwait(false);
1220+
return ms.ToArray();
1221+
}
1222+
}
1223+
11751224
protected void WriteRawParameter(IXdrWriter xdr, DbField field)
11761225
{
11771226
if (field.DbDataType != DbDataType.Null)
@@ -1749,55 +1798,15 @@ protected virtual async ValueTask<DbValue[]> ReadRowAsync(CancellationToken canc
17491798

17501799
#region Protected Internal Methods
17511800

1752-
protected internal virtual byte[] WriteParameters()
1801+
protected internal byte[] GetParameterData(IDescriptorFiller descriptorFiller, int index)
17531802
{
1754-
if (_parameters == null)
1755-
return null;
1756-
1757-
using (var ms = new MemoryStream())
1758-
{
1759-
var xdr = new XdrReaderWriter(new DataProviderStreamWrapper(ms), _database.Charset);
1760-
for (var i = 0; i < _parameters.Count; i++)
1761-
{
1762-
var field = _parameters[i];
1763-
try
1764-
{
1765-
WriteRawParameter(xdr, field);
1766-
xdr.Write(field.NullFlag);
1767-
}
1768-
catch (IOException ex)
1769-
{
1770-
throw IscException.ForIOException(ex);
1771-
}
1772-
}
1773-
xdr.Flush();
1774-
return ms.ToArray();
1775-
}
1803+
descriptorFiller.Fill(_parameters, index);
1804+
return WriteParameters();
17761805
}
1777-
protected internal virtual async ValueTask<byte[]> WriteParametersAsync(CancellationToken cancellationToken = default)
1806+
protected internal async ValueTask<byte[]> GetParameterDataAsync(IDescriptorFiller descriptorFiller, int index, CancellationToken cancellationToken = default)
17781807
{
1779-
if (_parameters == null)
1780-
return null;
1781-
1782-
using (var ms = new MemoryStream())
1783-
{
1784-
var xdr = new XdrReaderWriter(new DataProviderStreamWrapper(ms), _database.Charset);
1785-
for (var i = 0; i < _parameters.Count; i++)
1786-
{
1787-
var field = _parameters[i];
1788-
try
1789-
{
1790-
await WriteRawParameterAsync(xdr, field, cancellationToken).ConfigureAwait(false);
1791-
await xdr.WriteAsync(field.NullFlag, cancellationToken).ConfigureAwait(false);
1792-
}
1793-
catch (IOException ex)
1794-
{
1795-
throw IscException.ForIOException(ex);
1796-
}
1797-
}
1798-
await xdr.FlushAsync(cancellationToken).ConfigureAwait(false);
1799-
return ms.ToArray();
1800-
}
1808+
await descriptorFiller.FillAsync(_parameters, index, cancellationToken).ConfigureAwait(false);
1809+
return WriteParameters();
18011810
}
18021811

18031812
#endregion

src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version13/GdsStatement.cs

Lines changed: 61 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -40,66 +40,7 @@ public GdsStatement(GdsDatabase database, Version10.GdsTransaction transaction)
4040

4141
#region Overriden Methods
4242

43-
protected override DbValue[] ReadRow()
44-
{
45-
var row = new DbValue[_fields.Count];
46-
try
47-
{
48-
if (_fields.Count > 0)
49-
{
50-
var nullBytes = _database.Xdr.ReadOpaque((int)Math.Ceiling(_fields.Count / 8d));
51-
var nullBits = new BitArray(nullBytes);
52-
for (var i = 0; i < _fields.Count; i++)
53-
{
54-
if (nullBits.Get(i))
55-
{
56-
row[i] = new DbValue(this, _fields[i], null);
57-
}
58-
else
59-
{
60-
var value = ReadRawValue(_database.Xdr, _fields[i]);
61-
row[i] = new DbValue(this, _fields[i], value);
62-
}
63-
}
64-
}
65-
}
66-
catch (IOException ex)
67-
{
68-
throw IscException.ForIOException(ex);
69-
}
70-
return row;
71-
}
72-
protected override async ValueTask<DbValue[]> ReadRowAsync(CancellationToken cancellationToken = default)
73-
{
74-
var row = new DbValue[_fields.Count];
75-
try
76-
{
77-
if (_fields.Count > 0)
78-
{
79-
var nullBytes = await _database.Xdr.ReadOpaqueAsync((int)Math.Ceiling(_fields.Count / 8d), cancellationToken).ConfigureAwait(false);
80-
var nullBits = new BitArray(nullBytes);
81-
for (var i = 0; i < _fields.Count; i++)
82-
{
83-
if (nullBits.Get(i))
84-
{
85-
row[i] = new DbValue(this, _fields[i], null);
86-
}
87-
else
88-
{
89-
var value = await ReadRawValueAsync(_database.Xdr, _fields[i], cancellationToken).ConfigureAwait(false);
90-
row[i] = new DbValue(this, _fields[i], value);
91-
}
92-
}
93-
}
94-
}
95-
catch (IOException ex)
96-
{
97-
throw IscException.ForIOException(ex);
98-
}
99-
return row;
100-
}
101-
102-
protected internal override byte[] WriteParameters()
43+
protected override byte[] WriteParameters()
10344
{
10445
if (_parameters == null)
10546
return null;
@@ -144,7 +85,7 @@ protected internal override byte[] WriteParameters()
14485
}
14586
}
14687
}
147-
protected internal override async ValueTask<byte[]> WriteParametersAsync(CancellationToken cancellationToken = default)
88+
protected override async ValueTask<byte[]> WriteParametersAsync(CancellationToken cancellationToken = default)
14889
{
14990
if (_parameters == null)
15091
return null;
@@ -190,5 +131,64 @@ protected internal override async ValueTask<byte[]> WriteParametersAsync(Cancell
190131
}
191132
}
192133

134+
protected override DbValue[] ReadRow()
135+
{
136+
var row = new DbValue[_fields.Count];
137+
try
138+
{
139+
if (_fields.Count > 0)
140+
{
141+
var nullBytes = _database.Xdr.ReadOpaque((int)Math.Ceiling(_fields.Count / 8d));
142+
var nullBits = new BitArray(nullBytes);
143+
for (var i = 0; i < _fields.Count; i++)
144+
{
145+
if (nullBits.Get(i))
146+
{
147+
row[i] = new DbValue(this, _fields[i], null);
148+
}
149+
else
150+
{
151+
var value = ReadRawValue(_database.Xdr, _fields[i]);
152+
row[i] = new DbValue(this, _fields[i], value);
153+
}
154+
}
155+
}
156+
}
157+
catch (IOException ex)
158+
{
159+
throw IscException.ForIOException(ex);
160+
}
161+
return row;
162+
}
163+
protected override async ValueTask<DbValue[]> ReadRowAsync(CancellationToken cancellationToken = default)
164+
{
165+
var row = new DbValue[_fields.Count];
166+
try
167+
{
168+
if (_fields.Count > 0)
169+
{
170+
var nullBytes = await _database.Xdr.ReadOpaqueAsync((int)Math.Ceiling(_fields.Count / 8d), cancellationToken).ConfigureAwait(false);
171+
var nullBits = new BitArray(nullBytes);
172+
for (var i = 0; i < _fields.Count; i++)
173+
{
174+
if (nullBits.Get(i))
175+
{
176+
row[i] = new DbValue(this, _fields[i], null);
177+
}
178+
else
179+
{
180+
var value = await ReadRawValueAsync(_database.Xdr, _fields[i], cancellationToken).ConfigureAwait(false);
181+
row[i] = new DbValue(this, _fields[i], value);
182+
}
183+
}
184+
}
185+
}
186+
catch (IOException ex)
187+
{
188+
throw IscException.ForIOException(ex);
189+
}
190+
return row;
191+
}
192+
193193
#endregion
194194
}

src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version16/GdsBatch.cs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,8 @@ public GdsBatch(GdsStatement statement)
3838

3939
public override ExecuteResultItem[] Execute(int count, IDescriptorFiller descriptorFiller)
4040
{
41-
var parametersData = new byte[count][];
42-
for (var i = 0; i < parametersData.Length; i++)
43-
{
44-
descriptorFiller.Fill(_statement.Parameters, i);
45-
// this may throw error, so it needs to be before any writing
46-
parametersData[i] = _statement.WriteParameters();
47-
}
41+
// this may throw error, so it needs to be before any writing
42+
var parametersData = GetParametersData(count, descriptorFiller);
4843

4944
Database.Xdr.Write(IscCodes.op_batch_create);
5045
Database.Xdr.Write(_statement.Handle); // p_batch_statement
@@ -60,6 +55,7 @@ public override ExecuteResultItem[] Execute(int count, IDescriptorFiller descrip
6055
{
6156
pb.Append(IscCodes.Batch.TAG_MULTIERROR, 1);
6257
}
58+
pb.Append(IscCodes.Batch.TAG_BUFFER_BYTES_SIZE, BatchBufferSize);
6359
Database.Xdr.WriteBuffer(pb.ToArray()); // p_batch_pb
6460

6561
Database.Xdr.Write(IscCodes.op_batch_msg);
@@ -95,13 +91,8 @@ public override ExecuteResultItem[] Execute(int count, IDescriptorFiller descrip
9591
}
9692
public override async ValueTask<ExecuteResultItem[]> ExecuteAsync(int count, IDescriptorFiller descriptorFiller, CancellationToken cancellationToken = default)
9793
{
98-
var parametersData = new byte[count][];
99-
for (var i = 0; i < parametersData.Length; i++)
100-
{
101-
await descriptorFiller.FillAsync(_statement.Parameters, i, cancellationToken).ConfigureAwait(false);
102-
// this may throw error, so it needs to be before any writing
103-
parametersData[i] = await _statement.WriteParametersAsync(cancellationToken).ConfigureAwait(false);
104-
}
94+
// this may throw error, so it needs to be before any writing
95+
var parametersData = await GetParametersDataAsync(count, descriptorFiller, cancellationToken).ConfigureAwait(false);
10596

10697
await Database.Xdr.WriteAsync(IscCodes.op_batch_create, cancellationToken).ConfigureAwait(false);
10798
await Database.Xdr.WriteAsync(_statement.Handle, cancellationToken).ConfigureAwait(false); // p_batch_statement
@@ -117,6 +108,7 @@ public override async ValueTask<ExecuteResultItem[]> ExecuteAsync(int count, IDe
117108
{
118109
pb.Append(IscCodes.Batch.TAG_MULTIERROR, 1);
119110
}
111+
pb.Append(IscCodes.Batch.TAG_BUFFER_BYTES_SIZE, BatchBufferSize);
120112
await Database.Xdr.WriteBufferAsync(pb.ToArray(), cancellationToken).ConfigureAwait(false); // p_batch_pb
121113

122114
await Database.Xdr.WriteAsync(IscCodes.op_batch_msg, cancellationToken).ConfigureAwait(false);
@@ -212,4 +204,23 @@ protected ExecuteResultItem[] BuildResult(BatchCompletionStateResponse response)
212204
}
213205
return result;
214206
}
207+
208+
protected byte[][] GetParametersData(int count, IDescriptorFiller descriptorFiller)
209+
{
210+
var parametersData = new byte[count][];
211+
for (var i = 0; i < parametersData.Length; i++)
212+
{
213+
parametersData[i] = _statement.GetParameterData(descriptorFiller, i);
214+
}
215+
return parametersData;
216+
}
217+
protected async ValueTask<byte[][]> GetParametersDataAsync(int count, IDescriptorFiller descriptorFiller, CancellationToken cancellationToken = default)
218+
{
219+
var parametersData = new byte[count][];
220+
for (var i = 0; i < parametersData.Length; i++)
221+
{
222+
parametersData[i] = await _statement.GetParameterDataAsync(descriptorFiller, i, cancellationToken).ConfigureAwait(false);
223+
}
224+
return parametersData;
225+
}
215226
}

src/FirebirdSql.Data.FirebirdClient/Common/BatchBase.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ internal abstract class BatchBase
2424
{
2525
public abstract StatementBase Statement { get; }
2626
public bool MultiError { get; set; }
27+
public int BatchBufferSize { get; set; }
2728

2829
public class ExecuteResultItem
2930
{

src/FirebirdSql.Data.FirebirdClient/Common/PageSizeHelper.cs renamed to src/FirebirdSql.Data.FirebirdClient/Common/SizeHelper.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
namespace FirebirdSql.Data.Common;
2121

22-
internal static class PageSizeHelper
22+
internal static class SizeHelper
2323
{
2424
public static bool IsValidPageSize(int value)
2525
{
@@ -31,8 +31,13 @@ public static bool IsValidPageSize(int value)
3131
|| value == 32768;
3232
}
3333

34-
public static Exception InvalidPageSizeException()
34+
public static bool IsValidBatchBufferSize(int value)
3535
{
36-
return new InvalidOperationException("Invalid page size.");
36+
return value >= 0 && value <= 256 * 1024 * 1024;
37+
}
38+
39+
public static Exception InvalidSizeException(string what)
40+
{
41+
return new InvalidOperationException($"Invalid {what} size.");
3742
}
3843
}

0 commit comments

Comments
 (0)