forked from npgsql/npgsql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNpgsqlStatement.cs
More file actions
140 lines (122 loc) · 4.99 KB
/
NpgsqlStatement.cs
File metadata and controls
140 lines (122 loc) · 4.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Npgsql.BackendMessages;
namespace Npgsql
{
/// <summary>
/// Represents a single SQL statement within Npgsql.
///
/// Instances aren't constructed directly; users should construct an <see cref="NpgsqlCommand"/>
/// object and populate its <see cref="NpgsqlCommand.CommandText"/> property as in standard ADO.NET.
/// Npgsql will analyze that property and construct instances of <see cref="NpgsqlStatement"/>
/// internally.
///
/// Users can retrieve instances from <see cref="NpgsqlDataReader.Statements"/>
/// and access information about statement execution (e.g. affected rows).
/// </summary>
public sealed class NpgsqlStatement
{
/// <summary>
/// The SQL text of the statement.
/// </summary>
public string SQL { get; set; } = string.Empty;
/// <summary>
/// Specifies the type of query, e.g. SELECT.
/// </summary>
public StatementType StatementType { get; internal set; }
/// <summary>
/// The number of rows affected or retrieved.
/// </summary>
/// <remarks>
/// See the command tag in the CommandComplete message,
/// https://www.postgresql.org/docs/current/static/protocol-message-formats.html
/// </remarks>
public uint Rows => (uint)LongRows;
/// <summary>
/// The number of rows affected or retrieved.
/// </summary>
/// <remarks>
/// See the command tag in the CommandComplete message,
/// https://www.postgresql.org/docs/current/static/protocol-message-formats.html
/// </remarks>
public ulong LongRows { get; internal set; }
/// <summary>
/// For an INSERT, the object ID of the inserted row if <see cref="Rows"/> is 1 and
/// the target table has OIDs; otherwise 0.
/// </summary>
public uint OID { get; internal set; }
/// <summary>
/// The input parameters sent with this statement.
/// </summary>
public List<NpgsqlParameter> InputParameters
{
get => _inputParameters ??= _ownedInputParameters ??= new();
internal set => _inputParameters = value;
}
List<NpgsqlParameter>? _ownedInputParameters;
List<NpgsqlParameter>? _inputParameters;
/// <summary>
/// The RowDescription message for this query. If null, the query does not return rows (e.g. INSERT)
/// </summary>
internal RowDescriptionMessage? Description
{
get => PreparedStatement == null ? _description : PreparedStatement.Description;
set
{
if (PreparedStatement == null)
_description = value;
else
PreparedStatement.Description = value;
}
}
RowDescriptionMessage? _description;
/// <summary>
/// If this statement has been automatically prepared, references the <see cref="PreparedStatement"/>.
/// Null otherwise.
/// </summary>
internal PreparedStatement? PreparedStatement
{
get => _preparedStatement != null && _preparedStatement.State == PreparedState.Unprepared
? _preparedStatement = null
: _preparedStatement;
set => _preparedStatement = value;
}
PreparedStatement? _preparedStatement;
internal bool IsPreparing;
/// <summary>
/// Holds the server-side (prepared) statement name. Empty string for non-prepared statements.
/// </summary>
internal string StatementName => PreparedStatement?.Name ?? "";
/// <summary>
/// Whether this statement has already been prepared (including automatic preparation).
/// </summary>
internal bool IsPrepared => PreparedStatement?.IsPrepared == true;
internal void Reset()
{
SQL = string.Empty;
StatementType = StatementType.Select;
_description = null;
LongRows = 0;
OID = 0;
PreparedStatement = null;
if (ReferenceEquals(_inputParameters, _ownedInputParameters))
InputParameters.Clear();
else if (_inputParameters is not null)
_inputParameters = null; // We're pointing at a user's NpgsqlParameterCollection
Debug.Assert(_inputParameters is null || _inputParameters.Count == 0);
Debug.Assert(_ownedInputParameters is null || _ownedInputParameters.Count == 0);
}
internal void ApplyCommandComplete(CommandCompleteMessage msg)
{
StatementType = msg.StatementType;
LongRows = msg.Rows;
OID = msg.OID;
}
/// <summary>
/// Returns the SQL text of the statement.
/// </summary>
public override string ToString() => SQL ?? "<none>";
}
}