private Object FastpathV3(Int32 fnid, Boolean resulttype, FastpathArg[] args) { // give thread safety lock (stream) { // send the function call { Int32 l_msgLen = 0; l_msgLen += 16; for (Int32 i = 0; i < args.Length; i++) { l_msgLen += args[i].SendSize(); } stream .WriteByte(ASCIIByteArrays.FunctionCallMessageCode) .WriteInt32(l_msgLen) .WriteInt32(fnid) .WriteInt16(1) .WriteInt16(1) .WriteInt16((short)args.Length); for (Int32 i = 0; i < args.Length; i++) { args[i].Send(stream); } stream.WriteInt16(1); // This is needed, otherwise data can be lost stream.Flush(); } // Now handle the result // Now loop, reading the results Object result = null; // our result Exception error = null; Int32 c; Boolean l_endQuery = false; while (!l_endQuery) { c = (Char) stream.ReadByte(); switch (c) { case 'A': // Asynchronous Notify Int32 msglen = stream.ReadInt32(); Int32 pid = stream.ReadInt32(); String msg = stream.ReadString(); stream.ReadString(); String param = stream.ReadString(); break; //------------------------------ // Error message returned case 'E': NpgsqlError e = new NpgsqlError(stream); throw new NpgsqlException(e.ToString()); //------------------------------ // Notice from backend case 'N': Int32 l_nlen = stream.ReadInt32(); conn.Connector.FireNotice(new NpgsqlError(stream)); break; case 'V': Int32 l_msgLen = stream.ReadInt32(); Int32 l_valueLen = stream.ReadInt32(); if (l_valueLen == -1) { //null value } else if (l_valueLen == 0) { result = new Byte[0]; } else { // Return an Integer if if (resulttype) { result = stream.ReadInt32(); } else { Byte[] buf = new Byte[l_valueLen]; Int32 bytes_from_stream = 0; Int32 total_bytes_read = 0; Int32 size = l_valueLen; do { bytes_from_stream = stream.Read(buf, total_bytes_read, size); total_bytes_read += bytes_from_stream; size -= bytes_from_stream; } while (size > 0); result = buf; } } break; case 'Z': //TODO: use size better if (stream.ReadInt32() != 5) { throw new Exception("Received Z"); } //TODO: handle transaction status Char l_tStatus = (Char) stream.ReadByte(); l_endQuery = true; break; default: throw new Exception(string.Format("postgresql.fp.protocol received {0}", c)); } } if (error != null) { throw error; } return result; } }
internal NpgsqlException(NpgsqlError error) : base(error.ToString()) { this.errors = new NpgsqlError[1]; errors[0] = error; }
private Object FastpathV3(Int32 fnid, Boolean resulttype, FastpathArg[] args) { // give thread safety lock (stream) { // send the function call try { Int32 l_msgLen = 0; l_msgLen += 16; for (Int32 i=0;i < args.Length;i++) l_msgLen += args[i].SendSize(); stream.WriteByte((Byte)'F'); PGUtil.WriteInt32(stream,l_msgLen); PGUtil.WriteInt32(stream,fnid); PGUtil.WriteInt16(stream,1); PGUtil.WriteInt16(stream,1); PGUtil.WriteInt16(stream,(short)args.Length); for (Int32 i = 0;i < args.Length;i++) args[i].Send(stream); PGUtil.WriteInt16(stream,1); // This is needed, otherwise data can be lost stream.Flush(); } catch (Exception ex) { throw new Exception(ex.ToString()); } // Now handle the result // Now loop, reading the results Object result = null; // our result Exception error = null; Int32 c; Boolean l_endQuery = false; Byte[] input_buffer = new Byte[512]; while (!l_endQuery) { c = (Char)stream.ReadByte(); switch (c) { case 'A': // Asynchronous Notify Int32 msglen = PGUtil.ReadInt32(stream,input_buffer); Int32 pid = PGUtil.ReadInt32(stream,input_buffer); String msg = PGUtil.ReadString(stream,conn.Connector.Encoding); PGUtil.ReadString(stream,conn.Connector.Encoding); String param = PGUtil.ReadString(stream,conn.Connector.Encoding); conn.Connector.CheckErrorsAndNotifications(); break; //------------------------------ // Error message returned case 'E': NpgsqlError e = new NpgsqlError(conn.BackendProtocolVersion); e.ReadFromStream(stream,conn.Connector.Encoding); throw new Exception(e.ToString()); //------------------------------ // Notice from backend case 'N': Int32 l_nlen = PGUtil.ReadInt32(stream,input_buffer); NpgsqlError e1 = new NpgsqlError(conn.BackendProtocolVersion); e1.ReadFromStream(stream,conn.Connector.Encoding); conn.Connector.Mediator.Errors.Add(e1); break; case 'V': Int32 l_msgLen = PGUtil.ReadInt32(stream,input_buffer); Int32 l_valueLen = PGUtil.ReadInt32(stream,input_buffer); if (l_valueLen == -1) { //null value } else if (l_valueLen == 0) { result = new Byte[0]; } else { // Return an Integer if if (resulttype) result = PGUtil.ReadInt32(stream,input_buffer); else { Byte[] buf = new Byte[l_valueLen]; Int32 bytes_from_stream = 0; Int32 total_bytes_read = 0; Int32 size = l_valueLen; do { bytes_from_stream = stream.Read(buf, total_bytes_read, size); total_bytes_read += bytes_from_stream; size -= bytes_from_stream; } while(size > 0); result = buf; } } break; case 'Z': //TODO: use size better if (PGUtil.ReadInt32(stream,input_buffer) != 5) throw new Exception("Received Z" ); //TODO: handle transaction status Char l_tStatus = (Char)stream.ReadByte(); l_endQuery = true; break; default: throw new Exception("postgresql.fp.protocol received " + c.ToString()); } } if ( error != null ) throw error; return result; } }