/
dev-npgsql
/
npgsql
Обзор
Документация
Войти
/
dev-npgsql
/
npgsql
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
v6.0.12
src/Npgsql/PreparedStatement.cs
169 строк
5 KB
Shay Rojansky
Apply file-scoped namespaces for 6.0 (#4298)
28 янв 2022, 15:13
Не верифицирован
28 янв 2022, 15:13
2e0ad2d
Код
Авторство
О чём код?
using System; using System.Collections.Generic; using System.Diagnostics; using Npgsql.BackendMessages; namespace Npgsql; /// <summary> /// Internally represents a statement has been prepared, is in the process of being prepared, or is a /// candidate for preparation (i.e. awaiting further usages). /// </summary> [DebuggerDisplay("{Name} ({State}): {Sql}")] class PreparedStatement { readonly PreparedStatementManager _manager; internal string Sql { get; } internal string? Name; internal RowDescriptionMessage? Description; internal int Usages; internal PreparedState State { get; set; } internal bool IsPrepared => State == PreparedState.Prepared; /// <summary> /// If true, the user explicitly requested this statement be prepared. It does not get closed as part of /// the automatic preparation LRU mechanism. /// </summary> internal bool IsExplicit { get; } /// <summary> /// If this statement is about to be prepared, but replaces a previous statement which needs to be closed, /// this holds the name of the previous statement. Otherwise null. /// </summary> internal PreparedStatement? StatementBeingReplaced; internal int AutoPreparedSlotIndex { get; set; } internal DateTime LastUsed { get; set; } /// <summary> /// Contains the handler types for a prepared statement's parameters, for overloaded cases (same SQL, different param types) /// Only populated after the statement has been prepared (i.e. null for candidates). /// </summary> internal Type[]? HandlerParamTypes { get; private set; } static readonly Type[] EmptyParamTypes = Type.EmptyTypes; internal static PreparedStatement CreateExplicit( PreparedStatementManager manager, string sql, string name, List<NpgsqlParameter> parameters, PreparedStatement? statementBeingReplaced) { var pStatement = new PreparedStatement(manager, sql, true) { Name = name, StatementBeingReplaced = statementBeingReplaced }; pStatement.SetParamTypes(parameters); return pStatement; } internal static PreparedStatement CreateAutoPrepareCandidate(PreparedStatementManager manager, string sql) => new(manager, sql, false); PreparedStatement(PreparedStatementManager manager, string sql, bool isExplicit) { _manager = manager; Sql = sql; IsExplicit = isExplicit; State = PreparedState.NotPrepared; } internal void SetParamTypes(List<NpgsqlParameter> parameters) { Debug.Assert(HandlerParamTypes == null); if (parameters.Count == 0) { HandlerParamTypes = EmptyParamTypes; return; } HandlerParamTypes = new Type[parameters.Count]; for (var i = 0; i < parameters.Count; i++) HandlerParamTypes[i] = parameters[i].Handler!.GetType(); } internal bool DoParametersMatch(List<NpgsqlParameter> parameters) { if (HandlerParamTypes!.Length != parameters.Count) return false; for (var i = 0; i < HandlerParamTypes.Length; i++) if (HandlerParamTypes[i] != parameters[i].Handler!.GetType()) return false; return true; } internal void AbortPrepare() { Debug.Assert(State == PreparedState.BeingPrepared); // We were planned for preparation, but a failure occurred and we did not carry that out. // Remove it from the BySql dictionary, and place back the statement we were planned to replace (possibly null), setting // its state back to prepared. _manager.BySql.Remove(Sql); if (!IsExplicit) { _manager.AutoPrepared[AutoPreparedSlotIndex] = StatementBeingReplaced; if (StatementBeingReplaced is not null) StatementBeingReplaced.State = PreparedState.Prepared; } State = PreparedState.Unprepared; } internal void CompleteUnprepare() { _manager.BySql.Remove(Sql); _manager.NumPrepared--; State = PreparedState.Unprepared; } public override string ToString() => Sql; } /// <summary> /// The state of a <see cref="PreparedStatement"/>. /// </summary> enum PreparedState { /// <summary> /// The statement hasn't been prepared yet, nor is it in the process of being prepared. /// This is the value for autoprepare candidates which haven't been prepared yet, and is also /// a temporary state during preparation. /// </summary> NotPrepared, /// <summary> /// The statement is in the process of being prepared. /// </summary> BeingPrepared, /// <summary> /// The statement has been fully prepared and can be executed. /// </summary> Prepared, /// <summary> /// The statement is in the process of being unprepared. This is a temporary state that only occurs during /// unprepare. Specifically, it means that a Close message for the statement has already been written /// to the write buffer. /// </summary> BeingUnprepared, /// <summary> /// The statement has been unprepared and is no longer usable. /// </summary> Unprepared }