Skip to content

Commit ec8c025

Browse files
committed
New COPY implementation
A new API and implementation for COPY FROM STDIN and COPY IN STDIN. Supports both the high-performance binary protocol (with our new type handler system) and text, in which case writing/parsing is the user's responsibility. Moved processing of prepended messages responses to connector's ReadSingleMessage rather than doing it everywhere. Fixes #502
1 parent ab15025 commit ec8c025

75 files changed

Lines changed: 1831 additions & 2632 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Npgsql/BackendMessages/AuthenticationMessages.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
namespace Npgsql.BackendMessages
88
{
9-
internal abstract class AuthenticationRequestMessage : BackendMessage
9+
internal abstract class AuthenticationRequestMessage : IBackendMessage
1010
{
11-
internal override BackendMessageCode Code { get { return BackendMessageCode.AuthenticationRequest; } }
11+
public BackendMessageCode Code { get { return BackendMessageCode.AuthenticationRequest; } }
1212
internal abstract AuthenticationRequestType AuthRequestType { get; }
1313
}
1414

Npgsql/BackendMessages/BindCompleteMessage.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
namespace Npgsql.BackendMessages
77
{
8-
internal class BindCompleteMessage : BackendMessage
8+
internal class BindCompleteMessage : IBackendMessage
99
{
10-
internal override BackendMessageCode Code { get { return BackendMessageCode.BindComplete; } }
10+
public BackendMessageCode Code { get { return BackendMessageCode.BindComplete; } }
1111
internal static readonly BindCompleteMessage Instance = new BindCompleteMessage();
1212
BindCompleteMessage() { }
1313
}

Npgsql/BackendMessages/CloseCompletedMessage.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
namespace Npgsql.BackendMessages
22
{
3-
internal class CloseCompletedMessage : BackendMessage
3+
internal class CloseCompletedMessage : IBackendMessage
44
{
5-
internal override BackendMessageCode Code { get { return BackendMessageCode.CloseComplete; } }
5+
public BackendMessageCode Code { get { return BackendMessageCode.CloseComplete; } }
66
internal static readonly CloseCompletedMessage Instance = new CloseCompletedMessage();
77
CloseCompletedMessage() { }
88
}

Npgsql/BackendMessages/CommandCompleteMessage.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace Npgsql.BackendMessages
88
{
9-
internal class CommandCompleteMessage : BackendMessage
9+
internal class CommandCompleteMessage : IBackendMessage
1010
{
1111
internal uint? LastInsertedOID { get; private set; }
1212
internal uint? RowsAffected { get; private set; }
@@ -41,6 +41,6 @@ internal CommandCompleteMessage Load(NpgsqlBuffer buf, int len)
4141
return this;
4242
}
4343

44-
internal override BackendMessageCode Code { get { return BackendMessageCode.CompletedResponse; } }
44+
public BackendMessageCode Code { get { return BackendMessageCode.CompletedResponse; } }
4545
}
4646
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace Npgsql.BackendMessages
7+
{
8+
abstract class CopyResponseMessageBase : IBackendMessage
9+
{
10+
public abstract BackendMessageCode Code { get; }
11+
12+
internal bool IsBinary { get; private set; }
13+
internal short NumColumns { get; private set; }
14+
internal List<FormatCode> ColumnFormatCodes { get; private set; }
15+
16+
internal CopyResponseMessageBase()
17+
{
18+
ColumnFormatCodes = new List<FormatCode>();
19+
}
20+
21+
internal void Load(NpgsqlBuffer buf)
22+
{
23+
ColumnFormatCodes.Clear();
24+
25+
var binaryIndicator = buf.ReadByte();
26+
switch (binaryIndicator) {
27+
case 0:
28+
IsBinary = false;
29+
break;
30+
case 1:
31+
IsBinary = true;
32+
break;
33+
default:
34+
throw new Exception("Invalid binary indicator in CopyInResponse message: " + binaryIndicator);
35+
}
36+
37+
NumColumns = buf.ReadInt16();
38+
for (var i = 0; i < NumColumns; i++)
39+
ColumnFormatCodes.Add((FormatCode)buf.ReadInt16());
40+
}
41+
}
42+
43+
class CopyInResponseMessage : CopyResponseMessageBase
44+
{
45+
public override BackendMessageCode Code { get { return BackendMessageCode.CopyInResponse; } }
46+
47+
internal new CopyInResponseMessage Load(NpgsqlBuffer buf)
48+
{
49+
base.Load(buf);
50+
return this;
51+
}
52+
}
53+
54+
class CopyOutResponseMessage : CopyResponseMessageBase
55+
{
56+
public override BackendMessageCode Code { get { return BackendMessageCode.CopyOutResponse; } }
57+
58+
internal new CopyOutResponseMessage Load(NpgsqlBuffer buf)
59+
{
60+
base.Load(buf);
61+
return this;
62+
}
63+
}
64+
65+
class CopyBothResponseMessage : CopyResponseMessageBase
66+
{
67+
public override BackendMessageCode Code { get { return BackendMessageCode.CopyBothResponse; } }
68+
69+
internal new CopyBothResponseMessage Load(NpgsqlBuffer buf)
70+
{
71+
base.Load(buf);
72+
return this;
73+
}
74+
}
75+
76+
/// <summary>
77+
/// Note that this message doesn't actually contain the data, but only the length. Data is processed
78+
/// directly from the connector's buffer.
79+
/// </summary>
80+
class CopyDataMessage : IBackendMessage
81+
{
82+
public BackendMessageCode Code { get { return BackendMessageCode.CopyData; } }
83+
84+
public int Length { get; private set; }
85+
86+
internal CopyDataMessage Load(int len)
87+
{
88+
Length = len;
89+
return this;
90+
}
91+
}
92+
93+
/// <remarks>
94+
/// Note: This message is both a frontend and a backend message
95+
/// </remarks>
96+
class CopyDoneMessage : SimpleFrontendMessage, IBackendMessage
97+
{
98+
public BackendMessageCode Code { get { return BackendMessageCode.CopyDone; } }
99+
internal static readonly CopyDoneMessage Instance = new CopyDoneMessage();
100+
CopyDoneMessage() { }
101+
102+
internal override int Length { get { return 5; } }
103+
104+
internal override void Write(NpgsqlBuffer buf)
105+
{
106+
buf.WriteByte((byte)BackendMessageCode.CopyDone);
107+
buf.WriteInt32(4);
108+
}
109+
}
110+
}

Npgsql/BackendMessages/DataRowMessage.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99

1010
namespace Npgsql.BackendMessages
1111
{
12-
abstract class DataRowMessage : BackendMessage
12+
abstract class DataRowMessage : IBackendMessage
1313
{
14-
internal override BackendMessageCode Code { get { return BackendMessageCode.DataRow; } }
14+
public BackendMessageCode Code { get { return BackendMessageCode.DataRow; } }
1515

1616
protected internal NpgsqlBuffer Buffer { get; protected set; }
1717

Npgsql/BackendMessages/EmptyQueryMessage.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
namespace Npgsql.BackendMessages
77
{
8-
internal class EmptyQueryMessage : BackendMessage
8+
internal class EmptyQueryMessage : IBackendMessage
99
{
10-
internal override BackendMessageCode Code { get { return BackendMessageCode.EmptyQueryResponse; } }
10+
public BackendMessageCode Code { get { return BackendMessageCode.EmptyQueryResponse; } }
1111
internal static readonly EmptyQueryMessage Instance = new EmptyQueryMessage();
1212
EmptyQueryMessage() { }
1313
}

Npgsql/BackendMessages/NoDataMessage.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
namespace Npgsql.BackendMessages
77
{
8-
internal class NoDataMessage : BackendMessage
8+
internal class NoDataMessage : IBackendMessage
99
{
10-
internal override BackendMessageCode Code { get { return BackendMessageCode.NoData; } }
10+
public BackendMessageCode Code { get { return BackendMessageCode.NoData; } }
1111
internal static readonly NoDataMessage Instance = new NoDataMessage();
1212
NoDataMessage() { }
1313
}

Npgsql/BackendMessages/ParameterDescriptionMessage.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace Npgsql.BackendMessages
88
{
9-
internal class ParameterDescriptionMessage : BackendMessage
9+
internal class ParameterDescriptionMessage : IBackendMessage
1010
{
1111
internal List<uint> TypeOIDs { get; private set; }
1212

@@ -25,6 +25,6 @@ internal ParameterDescriptionMessage Load(NpgsqlBuffer buf)
2525
return this;
2626
}
2727

28-
internal override BackendMessageCode Code { get { return BackendMessageCode.ParameterDescription; } }
28+
public BackendMessageCode Code { get { return BackendMessageCode.ParameterDescription; } }
2929
}
3030
}

Npgsql/BackendMessages/ParseCompleteMessage.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
namespace Npgsql.BackendMessages
77
{
8-
internal class ParseCompleteMessage : BackendMessage
8+
internal class ParseCompleteMessage : IBackendMessage
99
{
10-
internal override BackendMessageCode Code { get { return BackendMessageCode.ParseComplete; } }
10+
public BackendMessageCode Code { get { return BackendMessageCode.ParseComplete; } }
1111
internal static readonly ParseCompleteMessage Instance = new ParseCompleteMessage();
1212
ParseCompleteMessage() { }
1313
}

0 commit comments

Comments
 (0)