// created on 12/7/2003 at 18:36
// Npgsql.NpgsqlError.cs
//
// Author:
// Francisco Jr. (fxjrlists@yahoo.com.br)
//
// Copyright (C) 2002 The Npgsql Development Team
// npgsql-general@gborg.postgresql.org
// http://gborg.postgresql.org/project/npgsql/projdisplay.php
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
using System.IO;
using System.Text;
namespace Npgsql
{
///
/// This class represents the ErrorResponse and NoticeResponse
/// message sent from PostgreSQL server.
///
///
public sealed class NpgsqlError
{
// Logging related values
private static readonly String CLASSNAME = "NpgsqlError";
private ProtocolVersion protocol_version;
private String _severity = "";
private String _code = "";
private String _message = "";
private String _detail = "";
private String _hint = "";
private String _position = "";
private String _where = "";
private String _file = "";
private String _line = "";
private String _routine = "";
///
/// Severity code. All versions.
///
public String Severity
{
get
{
return _severity;
}
}
///
/// Error code. PostgreSQL 7.4 and up.
///
public String Code
{
get
{
return _code;
}
}
///
/// Terse error message. All versions.
///
public String Message
{
get
{
return _message;
}
}
///
/// Detailed error message. PostgreSQL 7.4 and up.
///
public String Detail
{
get
{
return _detail;
}
}
///
/// Suggestion to help resolve the error. PostgreSQL 7.4 and up.
///
public String Hint
{
get
{
return _hint;
}
}
///
/// Position (one based) within the query string where the error was encounterd. PostgreSQL 7.4 and up.
///
public String Position
{
get
{
return _position;
}
}
///
/// Trace back information. PostgreSQL 7.4 and up.
///
public String Where
{
get
{
return _where;
}
}
///
/// Source file (in backend) reporting the error. PostgreSQL 7.4 and up.
///
public String File
{
get
{
return _file;
}
}
///
/// Source file line number (in backend) reporting the error. PostgreSQL 7.4 and up.
///
public String Line
{
get
{
return _line;
}
}
///
/// Source routine (in backend) reporting the error. PostgreSQL 7.4 and up.
///
public String Routine
{
get
{
return _routine;
}
}
///
/// Return a string representation of this error object.
///
public override String ToString()
{
StringBuilder B = new StringBuilder();
if (Severity.Length > 0)
{
B.AppendFormat("{0}: ", Severity);
}
if (Code.Length > 0)
{
B.AppendFormat("{0}: ", Code);
}
B.AppendFormat("{0}", Message);
// CHECKME - possibly multi-line, that is yucky
// if (Hint.Length > 0) {
// B.AppendFormat(" ({0})", Hint);
// }
return B.ToString();
}
private NpgsqlError()
{}
internal NpgsqlError(ProtocolVersion protocolVersion)
{
protocol_version = protocolVersion;
}
///
/// Backend protocol version in use.
///
internal ProtocolVersion BackendProtocolVersion
{
get
{
return protocol_version;
}
}
internal void ReadFromStream(Stream inputStream, Encoding encoding)
{
switch (protocol_version) {
case ProtocolVersion.Version2 :
ReadFromStream_Ver_2(inputStream, encoding);
break;
case ProtocolVersion.Version3 :
ReadFromStream_Ver_3(inputStream, encoding);
break;
}
}
private void ReadFromStream_Ver_2(Stream inputStream, Encoding encoding)
{
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream_Ver_2");
String Raw;
String[] Parts;
Raw = PGUtil.ReadString(inputStream, encoding);
Parts = Raw.Split(new char[] {':'}, 2);
if (Parts.Length == 2)
{
_severity = Parts[0].Trim();
_message = Parts[1].Trim();
}
else
{
_message = Parts[0].Trim();
}
}
private void ReadFromStream_Ver_3(Stream inputStream, Encoding encoding)
{
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream_Ver_3");
Int32 messageLength = PGUtil.ReadInt32(inputStream, new Byte[4]);
// [TODO] Would this be the right way to do?
// Check the messageLength value. If it is 1178686529, this would be the
// "FATA" string, which would mean a protocol 2.0 error string.
if (messageLength == 1178686529)
{
String Raw;
String[] Parts;
Raw = "FATA" + PGUtil.ReadString(inputStream, encoding);
Parts = Raw.Split(new char[] {':'}, 2);
if (Parts.Length == 2)
{
_severity = Parts[0].Trim();
_message = Parts[1].Trim();
}
else
{
_message = Parts[0].Trim();
}
protocol_version = ProtocolVersion.Version2;
return;
}
Char field;
String fieldValue;
field = (Char) inputStream.ReadByte();
// Now start to read fields.
while (field != 0)
{
fieldValue = PGUtil.ReadString(inputStream, encoding);
switch (field)
{
case 'S':
_severity = fieldValue;
break;
case 'C':
_code = fieldValue;
break;
case 'M':
_message = fieldValue;
break;
case 'D':
_detail = fieldValue;
break;
case 'H':
_hint = fieldValue;
break;
case 'P':
_position = fieldValue;
break;
case 'W':
_where = fieldValue;
break;
case 'F':
_file = fieldValue;
break;
case 'L':
_line = fieldValue;
break;
case 'R':
_routine = fieldValue;
break;
}
field = (Char) inputStream.ReadByte();
}
}
}
}