using System; using Npgsql.BackendMessages; using Npgsql.Internal; namespace Npgsql; /// /// PostgreSQL notices are non-critical messages generated by PostgreSQL, either as a result of a user query /// (e.g. as a warning or informational notice), or due to outside activity (e.g. if the database administrator /// initiates a "fast" database shutdown). /// /// /// https://www.postgresql.org/docs/current/static/protocol-flow.html#PROTOCOL-ASYNC /// public sealed class PostgresNotice { #region Message Fields /// /// Severity of the error or notice. /// Always present. /// public string Severity { get; set; } /// /// Severity of the error or notice, not localized. /// Always present since PostgreSQL 9.6. /// public string InvariantSeverity { get; } /// /// The SQLSTATE code for the error. /// /// /// Always present. /// See https://www.postgresql.org/docs/current/static/errcodes-appendix.html /// public string SqlState { get; set; } /// /// The SQLSTATE code for the error. /// /// /// Always present. /// See https://www.postgresql.org/docs/current/static/errcodes-appendix.html /// [Obsolete("Use SqlState instead")] public string Code => SqlState; /// /// The primary human-readable error message. This should be accurate but terse. /// /// /// Always present. /// public string MessageText { get; set; } /// /// An optional secondary error message carrying more detail about the problem. /// May run to multiple lines. /// public string? Detail { get; set; } /// /// An optional suggestion what to do about the problem. /// This is intended to differ from Detail in that it offers advice (potentially inappropriate) rather than hard facts. /// May run to multiple lines. /// public string? Hint { get; set; } /// /// The field value is a decimal ASCII integer, indicating an error cursor position as an index into the original query string. /// The first character has index 1, and positions are measured in characters not bytes. /// 0 means not provided. /// public int Position { get; set; } /// /// This is defined the same as the field, but it is used when the cursor position refers to an internally generated command rather than the one submitted by the client. /// The field will always appear when this field appears. /// 0 means not provided. /// public int InternalPosition { get; set; } /// /// The text of a failed internally-generated command. /// This could be, for example, a SQL query issued by a PL/pgSQL function. /// public string? InternalQuery { get; set; } /// /// An indication of the context in which the error occurred. /// Presently this includes a call stack traceback of active PL functions. /// The trace is one entry per line, most recent first. /// public string? Where { get; set; } /// /// If the error was associated with a specific database object, the name of the schema containing that object, if any. /// /// PostgreSQL 9.3 and up. public string? SchemaName { get; set; } /// /// Table name: if the error was associated with a specific table, the name of the table. /// (Refer to the schema name field for the name of the table's schema.) /// /// PostgreSQL 9.3 and up. public string? TableName { get; set; } /// /// If the error was associated with a specific table column, the name of the column. /// (Refer to the schema and table name fields to identify the table.) /// /// PostgreSQL 9.3 and up. public string? ColumnName { get; set; } /// /// If the error was associated with a specific data type, the name of the data type. /// (Refer to the schema name field for the name of the data type's schema.) /// /// PostgreSQL 9.3 and up. public string? DataTypeName { get; set; } /// /// If the error was associated with a specific constraint, the name of the constraint. /// Refer to fields listed above for the associated table or domain. /// (For this purpose, indexes are treated as constraints, even if they weren't created with constraint syntax.) /// /// PostgreSQL 9.3 and up. public string? ConstraintName { get; set; } /// /// The file name of the source-code location where the error was reported. /// /// PostgreSQL 9.3 and up. public string? File { get; set; } /// /// The line number of the source-code location where the error was reported. /// public string? Line { get; set; } /// /// The name of the source-code routine reporting the error. /// public string? Routine { get; set; } #endregion /// /// Creates a new instance. /// public PostgresNotice(string severity, string invariantSeverity, string sqlState, string messageText) : this(messageText, severity, invariantSeverity, sqlState, detail: null) {} /// /// Creates a new instance. /// public PostgresNotice( string messageText, string severity, string invariantSeverity, string sqlState, string? detail = null, string? hint = null, int position = 0, int internalPosition = 0, string? internalQuery = null, string? where = null, string? schemaName = null, string? tableName = null, string? columnName = null, string? dataTypeName = null, string? constraintName = null, string? file = null, string? line = null, string? routine = null) { MessageText = messageText; Severity = severity; InvariantSeverity = invariantSeverity; SqlState = sqlState; Detail = detail; Hint = hint; Position = position; InternalPosition = internalPosition; InternalQuery = internalQuery; Where = where; SchemaName = schemaName; TableName = tableName; ColumnName = columnName; DataTypeName = dataTypeName; ConstraintName = constraintName; File = file; Line = line; Routine = routine; } PostgresNotice(ErrorOrNoticeMessage msg) : this( msg.Message, msg.Severity, msg.InvariantSeverity, msg.SqlState, msg.Detail, msg.Hint, msg.Position, msg.InternalPosition, msg.InternalQuery, msg.Where, msg.SchemaName, msg.TableName, msg.ColumnName, msg.DataTypeName, msg.ConstraintName, msg.File, msg.Line, msg.Routine) {} internal static PostgresNotice Load(NpgsqlReadBuffer buf, bool includeDetail) => new(ErrorOrNoticeMessage.Load(buf, includeDetail)); } /// /// Provides data for a PostgreSQL notice event. /// public sealed class NpgsqlNoticeEventArgs : EventArgs { /// /// The Notice that was sent from the database. /// public PostgresNotice Notice { get; } internal NpgsqlNoticeEventArgs(PostgresNotice notice) { Notice = notice; } }