Make System.Web.Script.Serialization.JavaScriptSerializer.ConvertToType(Type, object...
[mono.git] / mcs / class / Npgsql / Npgsql / NpgsqlError.cs
1 // created on 12/7/2003 at 18:36
2
3 // Npgsql.NpgsqlError.cs
4 //
5 // Author:
6 //      Francisco Jr. (fxjrlists@yahoo.com.br)
7 //
8 //      Copyright (C) 2002 The Npgsql Development Team
9 //      npgsql-general@gborg.postgresql.org
10 //      http://gborg.postgresql.org/project/npgsql/projdisplay.php
11 //
12 // This library is free software; you can redistribute it and/or
13 // modify it under the terms of the GNU Lesser General Public
14 // License as published by the Free Software Foundation; either
15 // version 2.1 of the License, or (at your option) any later version.
16 //
17 // This library is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 // Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License along with this library; if not, write to the Free Software
24 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
26 using System;
27 using System.IO;
28 using System.Text;
29
30 namespace Npgsql
31 {
32     /// <summary>
33     /// EventArgs class to send Notice parameters, which are just NpgsqlError's in a lighter context.
34     /// </summary>
35     public class NpgsqlNoticeEventArgs : EventArgs
36     {
37         /// <summary>
38         /// Notice information.
39         /// </summary>
40         public NpgsqlError Notice = null;
41
42         internal NpgsqlNoticeEventArgs(NpgsqlError eNotice)
43         {
44             Notice = eNotice;
45         }
46     }
47
48     /// <summary>
49     /// This class represents the ErrorResponse and NoticeResponse
50     /// message sent from PostgreSQL server.
51     /// </summary>
52     [Serializable]
53     public sealed class NpgsqlError
54     {
55         // Logging related values
56         private static readonly String CLASSNAME = "NpgsqlError";
57
58         private ProtocolVersion protocol_version;
59         private String _severity = String.Empty;
60         private String _code = String.Empty;
61         private String _message = String.Empty;
62         private String _detail = String.Empty;
63         private String _hint = String.Empty;
64         private String _position = String.Empty;
65         private String _where = String.Empty;
66         private String _file = String.Empty;
67         private String _line = String.Empty;
68         private String _routine = String.Empty;
69         private String _errorSql = String.Empty;
70
71         /// <summary>
72         /// Severity code.  All versions.
73         /// </summary>
74         public String Severity
75         {
76             get
77             {
78                 return _severity;
79             }
80         }
81
82         /// <summary>
83         /// Error code.  PostgreSQL 7.4 and up.
84         /// </summary>
85         public String Code
86         {
87             get
88             {
89                 return _code;
90             }
91         }
92
93         /// <summary>
94         /// Terse error message.  All versions.
95         /// </summary>
96         public String Message
97         {
98             get
99             {
100                 return _message;
101             }
102         }
103
104         /// <summary>
105         /// Detailed error message.  PostgreSQL 7.4 and up.
106         /// </summary>
107         public String Detail
108         {
109             get
110             {
111                 return _detail;
112             }
113         }
114
115         /// <summary>
116         /// Suggestion to help resolve the error.  PostgreSQL 7.4 and up.
117         /// </summary>
118         public String Hint
119         {
120             get
121             {
122                 return _hint;
123             }
124         }
125
126         /// <summary>
127         /// Position (one based) within the query string where the error was encounterd.  PostgreSQL 7.4 and up.
128         /// </summary>
129         public String Position
130         {
131             get
132             {
133                 return _position;
134             }
135         }
136
137         /// <summary>
138         /// Trace back information.  PostgreSQL 7.4 and up.
139         /// </summary>
140         public String Where
141         {
142             get
143             {
144                 return _where;
145             }
146         }
147
148         /// <summary>
149         /// Source file (in backend) reporting the error.  PostgreSQL 7.4 and up.
150         /// </summary>
151         public String File
152         {
153             get
154             {
155                 return _file;
156             }
157         }
158
159         /// <summary>
160         /// Source file line number (in backend) reporting the error.  PostgreSQL 7.4 and up.
161         /// </summary>
162         public String Line
163         {
164             get
165             {
166                 return _line;
167             }
168         }
169
170         /// <summary>
171         /// Source routine (in backend) reporting the error.  PostgreSQL 7.4 and up.
172         /// </summary>
173         public String Routine
174         {
175             get
176             {
177                 return _routine;
178             }
179         }
180         
181         /// <summary>
182         /// String containing the sql sent which produced this error.
183         /// </summary>
184         public String ErrorSql
185         {
186             set
187             {
188                 _errorSql = value;
189             }
190             get
191             {
192                 return _errorSql;
193             }
194         }
195         /// <summary>
196         /// Return a string representation of this error object.
197         /// </summary>
198         public override String ToString()
199         {
200             StringBuilder     B = new StringBuilder();
201
202             if (Severity.Length > 0)
203             {
204                 B.AppendFormat("{0}: ", Severity);
205             }
206             if (Code.Length > 0)
207             {
208                 B.AppendFormat("{0}: ", Code);
209             }
210             B.AppendFormat("{0}", Message);
211             // CHECKME - possibly multi-line, that is yucky
212             //            if (Hint.Length > 0) {
213             //                B.AppendFormat(" ({0})", Hint);
214             //            }
215
216             return B.ToString();
217         }
218
219         internal NpgsqlError(ProtocolVersion protocolVersion)
220         {
221             protocol_version = protocolVersion;
222         }
223         
224         internal NpgsqlError(ProtocolVersion protocolVersion, String errorMessage)
225         {
226             protocol_version = protocolVersion;
227             _message = errorMessage;
228         }
229
230         /// <summary>
231         /// Backend protocol version in use.
232         /// </summary>
233         internal ProtocolVersion BackendProtocolVersion
234         {
235             get
236             {
237                 return protocol_version;
238             }
239         }
240
241         internal void ReadFromStream(Stream inputStream, Encoding encoding)
242         {
243             switch (protocol_version) {
244             case ProtocolVersion.Version2 :
245                 ReadFromStream_Ver_2(inputStream, encoding);
246                 break;
247
248             case ProtocolVersion.Version3 :
249                 ReadFromStream_Ver_3(inputStream, encoding);
250                 break;
251
252             }
253         }
254
255         private void ReadFromStream_Ver_2(Stream inputStream, Encoding encoding)
256         {
257             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream_Ver_2");
258
259             String Raw;
260             String[] Parts;
261
262             Raw = PGUtil.ReadString(inputStream, encoding);
263
264             Parts = Raw.Split(new char[] {':'}, 2);
265
266             if (Parts.Length == 2)
267             {
268                 _severity = Parts[0].Trim();
269                 _message = Parts[1].Trim();
270             }
271             else
272             {
273                 _message = Parts[0].Trim();
274             }
275         }
276
277         private void ReadFromStream_Ver_3(Stream inputStream, Encoding encoding)
278         {
279             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream_Ver_3");
280
281             Int32 messageLength = PGUtil.ReadInt32(inputStream, new Byte[4]);
282
283             // [TODO] Would this be the right way to do?
284             // Check the messageLength value. If it is 1178686529, this would be the
285             // "FATA" string, which would mean a protocol 2.0 error string.
286             if (messageLength == 1178686529)
287             {
288                                                                 String Raw;
289                 String[] Parts;
290
291                 Raw = "FATA" + PGUtil.ReadString(inputStream, encoding);
292
293                 Parts = Raw.Split(new char[] {':'}, 2);
294
295                 if (Parts.Length == 2)
296                 {
297                     _severity = Parts[0].Trim();
298                     _message = Parts[1].Trim();
299                 }
300                 else
301                 {
302                     _message = Parts[0].Trim();
303                 }
304
305                 protocol_version = ProtocolVersion.Version2;
306
307                 return;
308             }
309
310             Char field;
311             String fieldValue;
312
313             field = (Char) inputStream.ReadByte();
314
315             // Now start to read fields.
316             while (field != 0)
317             {
318                 fieldValue = PGUtil.ReadString(inputStream, encoding);
319
320                 switch (field)
321                 {
322                 case 'S':
323                     _severity = fieldValue;
324                     break;
325                 case 'C':
326                     _code = fieldValue;
327                     break;
328                 case 'M':
329                     _message = fieldValue;
330                     break;
331                 case 'D':
332                     _detail = fieldValue;
333                     break;
334                 case 'H':
335                     _hint = fieldValue;
336                     break;
337                 case 'P':
338                     _position = fieldValue;
339                     break;
340                 case 'W':
341                     _where = fieldValue;
342                     break;
343                 case 'F':
344                     _file = fieldValue;
345                     break;
346                 case 'L':
347                     _line = fieldValue;
348                     break;
349                 case 'R':
350                     _routine = fieldValue;
351                     break;
352
353                 }
354
355                 field = (Char) inputStream.ReadByte();
356
357             }
358         }
359     }
360 }