Implement PG mock for testing (#3207) · npgsql/npgsql@e34709d · GitHub
Skip to content

Commit e34709d

Browse files
authored
Implement PG mock for testing (#3207)
With two tests to exercise hard cancellation/timeout. Closes #3193
1 parent eb180f9 commit e34709d

18 files changed

Lines changed: 661 additions & 122 deletions

‎src/Npgsql/BackendMessages/CommandCompleteMessage.cs‎

Lines changed: 1 addition & 1 deletion

‎src/Npgsql/BackendMessages/RowDescriptionMessage.cs‎

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,22 @@ public sealed class FieldDescription
138138
{
139139
#pragma warning disable CS8618 // Lazy-initialized type
140140
internal FieldDescription() {}
141+
142+
internal FieldDescription(uint oid)
143+
: this("?", 0, 0, oid, 0, 0, FormatCode.Binary) {}
144+
145+
internal FieldDescription(
146+
string name, uint tableOID, short columnAttributeNumber,
147+
uint oid, short typeSize, int typeModifier, FormatCode formatCode)
148+
{
149+
Name = name;
150+
TableOID = tableOID;
151+
ColumnAttributeNumber = columnAttributeNumber;
152+
TypeOID = oid;
153+
TypeSize = typeSize;
154+
TypeModifier = typeModifier;
155+
FormatCode = formatCode;
156+
}
141157
#pragma warning restore CS8618
142158

143159
internal FieldDescription(FieldDescription source)
@@ -178,7 +194,7 @@ internal void Populate(
178194
/// <summary>
179195
/// The object ID of the field's data type.
180196
/// </summary>
181-
internal uint TypeOID { get; private set; }
197+
internal uint TypeOID { get; set; }
182198

183199
/// <summary>
184200
/// The data type size (see pg_type.typlen). Note that negative values denote variable-width types.
@@ -205,17 +221,7 @@ internal void Populate(
205221
/// Currently will be zero (text) or one (binary).
206222
/// In a RowDescription returned from the statement variant of Describe, the format code is not yet known and will always be zero.
207223
/// </summary>
208-
internal FormatCode FormatCode
209-
{
210-
get => _formatCode;
211-
set
212-
{
213-
_formatCode = value;
214-
ResolveHandler();
215-
}
216-
}
217-
218-
FormatCode _formatCode;
224+
internal FormatCode FormatCode { get; set; }
219225

220226
internal string TypeDisplayName => PostgresType.GetDisplayNameWithFacets(TypeModifier);
221227

@@ -232,19 +238,20 @@ internal PostgresType PostgresType
232238

233239
internal Type FieldType => Handler.GetFieldType(this);
234240

235-
void ResolveHandler()
236-
{
237-
Handler = IsBinaryFormat
238-
? _typeMapper.GetByOID(TypeOID)
239-
: _typeMapper.UnrecognizedTypeHandler;
240-
}
241+
internal void ResolveHandler()
242+
=> Handler = IsBinaryFormat ? _typeMapper.GetByOID(TypeOID) : _typeMapper.UnrecognizedTypeHandler;
241243

242244
ConnectorTypeMapper _typeMapper;
243245

244246
internal bool IsBinaryFormat => FormatCode == FormatCode.Binary;
245247
internal bool IsTextFormat => FormatCode == FormatCode.Text;
246248

247-
internal FieldDescription Clone() => new FieldDescription(this);
249+
internal FieldDescription Clone()
250+
{
251+
var field = new FieldDescription(this);
252+
field.ResolveHandler();
253+
return field;
254+
}
248255

249256
/// <summary>
250257
/// Returns a string that represents the current object.

‎src/Npgsql/Common.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ enum BackendMessageCode : byte
1414
BackendKeyData = (byte)'K',
1515
BindComplete = (byte)'2',
1616
CloseComplete = (byte)'3',
17-
CompletedResponse = (byte)'C',
17+
CommandComplete = (byte)'C',
1818
CopyData = (byte)'d',
1919
CopyDone = (byte)'c',
2020
CopyBothResponse = (byte)'W',

‎src/Npgsql/NpgsqlBinaryExporter.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ internal NpgsqlBinaryExporter(NpgsqlConnector connector, string copyToCommand)
6464
nameof(copyToCommand)));
6565
}
6666
break;
67-
case BackendMessageCode.CompletedResponse:
67+
case BackendMessageCode.CommandComplete:
6868
throw new InvalidOperationException(
6969
"This API only supports import/export from the client, i.e. COPY commands containing TO/FROM STDIN. " +
7070
"To import/export with files on your PostgreSQL machine, simply execute the command with ExecuteNonQuery. " +

‎src/Npgsql/NpgsqlBinaryImporter.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ internal NpgsqlBinaryImporter(NpgsqlConnector connector, string copyFromCommand)
6868
nameof(copyFromCommand)));
6969
}
7070
break;
71-
case BackendMessageCode.CompletedResponse:
71+
case BackendMessageCode.CommandComplete:
7272
throw new InvalidOperationException(
7373
"This API only supports import/export from the client, i.e. COPY commands containing TO/FROM STDIN. " +
7474
"To import/export with files on your PostgreSQL machine, simply execute the command with ExecuteNonQuery. " +

‎src/Npgsql/NpgsqlCommand.cs‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1424,7 +1424,13 @@ protected override void Dispose(bool disposing)
14241424
internal void FixupRowDescription(RowDescriptionMessage rowDescription, bool isFirst)
14251425
{
14261426
for (var i = 0; i < rowDescription.NumFields; i++)
1427-
rowDescription[i].FormatCode = (UnknownResultTypeList == null || !isFirst ? AllResultTypesAreUnknown : UnknownResultTypeList[i]) ? FormatCode.Text : FormatCode.Binary;
1427+
{
1428+
var field = rowDescription[i];
1429+
field.FormatCode = (UnknownResultTypeList == null || !isFirst ? AllResultTypesAreUnknown : UnknownResultTypeList[i])
1430+
? FormatCode.Text
1431+
: FormatCode.Binary;
1432+
field.ResolveHandler();
1433+
}
14281434
}
14291435

14301436
void LogCommand()

‎src/Npgsql/NpgsqlConnector.cs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,7 @@ internal ValueTask<IBackendMessage> ReadMessage(bool async, DataRowLoadingMode d
12221222
return _rowDescriptionMessage.Load(buf, TypeMapper);
12231223
case BackendMessageCode.DataRow:
12241224
return _dataRowMessage.Load(len);
1225-
case BackendMessageCode.CompletedResponse:
1225+
case BackendMessageCode.CommandComplete:
12261226
return _commandCompleteMessage.Load(buf, len);
12271227
case BackendMessageCode.ReadyForQuery:
12281228
var rfq = _readyForQueryMessage.Load(buf);
@@ -2008,9 +2008,9 @@ internal async Task<bool> Wait(bool async, int timeout, CancellationToken cancel
20082008
case BackendMessageCode.DataRow:
20092009
// DataRow is usually consumed by a reader, here we have to skip it manually.
20102010
await ReadBuffer.Skip(((DataRowMessage)msg).Length, async, cancellationToken);
2011-
expectedMessageCode = BackendMessageCode.CompletedResponse;
2011+
expectedMessageCode = BackendMessageCode.CommandComplete;
20122012
continue;
2013-
case BackendMessageCode.CompletedResponse:
2013+
case BackendMessageCode.CommandComplete:
20142014
expectedMessageCode = BackendMessageCode.ReadyForQuery;
20152015
continue;
20162016
case BackendMessageCode.ReadyForQuery:

‎src/Npgsql/NpgsqlDataReader.cs‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ async Task<bool> NextResult(bool async, bool isConsuming = false, CancellationTo
349349
var completedMsg = await Connector.ReadMessage(async, DataRowLoadingMode.Skip, cancellationToken);
350350
switch (completedMsg.Code)
351351
{
352-
case BackendMessageCode.CompletedResponse:
352+
case BackendMessageCode.CommandComplete:
353353
case BackendMessageCode.EmptyQueryResponse:
354354
ProcessMessage(completedMsg);
355355
break;
@@ -440,7 +440,7 @@ async Task<bool> NextResult(bool async, bool isConsuming = false, CancellationTo
440440
msg = await ReadMessage(async, cancellationToken);
441441
switch (msg.Code)
442442
{
443-
case BackendMessageCode.CompletedResponse:
443+
case BackendMessageCode.CommandComplete:
444444
case BackendMessageCode.EmptyQueryResponse:
445445
break;
446446
default:
@@ -470,7 +470,7 @@ async Task<bool> NextResult(bool async, bool isConsuming = false, CancellationTo
470470
switch (msg.Code)
471471
{
472472
case BackendMessageCode.DataRow:
473-
case BackendMessageCode.CompletedResponse:
473+
case BackendMessageCode.CommandComplete:
474474
break;
475475
default:
476476
throw Connector.UnexpectedMessageReceived(msg.Code);
@@ -651,7 +651,7 @@ internal void ProcessMessage(IBackendMessage msg)
651651
ProcessDataRowMessage((DataRowMessage)msg);
652652
return;
653653

654-
case BackendMessageCode.CompletedResponse:
654+
case BackendMessageCode.CommandComplete:
655655
var completed = (CommandCompleteMessage)msg;
656656
switch (completed.StatementType)
657657
{
@@ -1793,7 +1793,7 @@ Task<ReadOnlyCollection<NpgsqlDbColumn>> GetColumnSchema(bool async, Cancellatio
17931793
/// </summary>
17941794
public override DataTable? GetSchemaTable()
17951795
=> GetSchemaTable(async: false).GetAwaiter().GetResult();
1796-
1796+
17971797
/// <summary>
17981798
/// Asynchronously returns a System.Data.DataTable that describes the column metadata of the DataReader.
17991799
/// </summary>

‎src/Npgsql/NpgsqlRawCopyStream.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ internal NpgsqlRawCopyStream(NpgsqlConnector connector, string copyCommand)
7575
IsBinary = copyOutResponse.IsBinary;
7676
_canRead = true;
7777
break;
78-
case BackendMessageCode.CompletedResponse:
78+
case BackendMessageCode.CommandComplete:
7979
throw new InvalidOperationException(
8080
"This API only supports import/export from the client, i.e. COPY commands containing TO/FROM STDIN. " +
8181
"To import/export with files on your PostgreSQL machine, simply execute the command with ExecuteNonQuery. " +

‎src/Npgsql/NpgsqlReadBuffer.cs‎

Lines changed: 5 additions & 1 deletion

0 commit comments

Comments
 (0)