示例#1
0
        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((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();
                }


                // 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 NpgsqlException(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 NpgsqlException("Received Z");
                        }
                        //TODO: handle transaction status
                        Char l_tStatus = (Char)stream.ReadByte();
                        l_endQuery = true;
                        break;

                    default:
                        throw new NpgsqlException("postgresql.fp.protocol received " + c.ToString());
                    }
                }

                if (error != null)
                {
                    throw error;
                }

                return(result);
            }
        }
示例#2
0
        private Object FastpathV2(Int32 fnid, Boolean resulttype, FastpathArg[] args)
        {
            // added Oct 7 1998 to give us thread safety
            lock (stream)
            {
                // send the function call

                // 70 is 'F' in ASCII. Note: don't use SendChar() here as it adds padding
                // that confuses the backend. The 0 terminates the command line.
                stream.WriteByte((Byte)70);
                stream.WriteByte((Byte)0);

                PGUtil.WriteInt32(stream, fnid);
                PGUtil.WriteInt32(stream, args.Length);


                for (Int32 i = 0; i < args.Length; i++)
                {
                    args[i].Send(stream);
                }

                // This is needed, otherwise data can be lost
                stream.Flush();


                // Now handle the result

                // Now loop, reading the results
                Object  result       = null; // our result
                String  errorMessage = "";
                Byte[]  input_buffer = new Byte[512];
                Int32   c;
                Boolean l_endQuery = false;
                while (!l_endQuery)
                {
                    c = (Char)stream.ReadByte();

                    switch (c)
                    {
                    case 'A':   // Asynchronous Notify
                        //TODO: do something with this
                        Int32  pid = PGUtil.ReadInt32(stream, input_buffer);
                        String msg = 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);
                        errorMessage += e.Message;
                        break;

                    //------------------------------
                    // Notice from backend
                    case 'N':
                        NpgsqlError notice = new NpgsqlError(conn.BackendProtocolVersion);
                        notice.ReadFromStream(stream, conn.Connector.Encoding);
                        errorMessage += notice.Message;
                        break;

                    case 'V':
                        Char l_nextChar = (Char)stream.ReadByte();
                        if (l_nextChar == 'G')
                        {
                            Int32 sz = PGUtil.ReadInt32(stream, input_buffer);
                            // Return an Integer if
                            if (resulttype)
                            {
                                result = PGUtil.ReadInt32(stream, input_buffer);
                            }
                            else
                            {
                                Byte[] buf = new Byte[sz];

                                Int32 bytes_from_stream = 0;
                                Int32 total_bytes_read  = 0;
                                Int32 size = sz;
                                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;
                            }
                            //There should be a trailing '0'
                            Int32 l_endChar = (Char)stream.ReadByte();
                        }
                        else
                        {
                            //it must have been a '0', thus no results
                        }
                        break;

                    case 'Z':
                        l_endQuery = true;
                        break;

                    default:
                        throw new NpgsqlException("postgresql.fp.protocol " + c.ToString());
                    }
                }

                if (errorMessage != null)
                {
                    throw new NpgsqlException("postgresql.fp.error" + errorMessage);
                }

                return(result);
            }
        }
示例#3
0
        private Object FastpathV2(Int32 fnid, Boolean resulttype, FastpathArg[] args)
        {
            // added Oct 7 1998 to give us thread safety
            lock (stream)
            {
                // send the function call

                stream
                .WriteBytesNullTerminated((byte)ASCIIBytes.F)
                .WriteInt32(fnid)
                .WriteInt32(args.Length);

                for (Int32 i = 0; i < args.Length; i++)
                {
                    args[i].Send(stream);
                }

                // This is needed, otherwise data can be lost
                stream.Flush();

                // Now handle the result

                // Now loop, reading the results
                Object  result       = null; // our result
                String  errorMessage = "";
                Int32   c;
                Boolean l_endQuery = false;
                while (!l_endQuery)
                {
                    c = (Char)stream.ReadByte();

                    switch (c)
                    {
                    case 'A':     // Asynchronous Notify
                        //TODO: do something with this
                        Int32  pid = PGUtil.ReadInt32(stream);
                        String msg = PGUtil.ReadString(stream);

                        break;

                    //------------------------------
                    // Error message returned
                    case 'E':
                        NpgsqlError e = new NpgsqlError(conn.BackendProtocolVersion, stream);
                        errorMessage += e.Message;
                        break;

                    //------------------------------
                    // Notice from backend
                    case 'N':
                        NpgsqlError notice = new NpgsqlError(conn.BackendProtocolVersion, stream);
                        errorMessage += notice.Message;
                        break;

                    case 'V':
                        Char l_nextChar = (Char)stream.ReadByte();
                        if (l_nextChar == 'G')
                        {
                            Int32 sz = PGUtil.ReadInt32(stream);
                            // Return an Integer if
                            if (resulttype)
                            {
                                result = PGUtil.ReadInt32(stream);
                            }
                            else
                            {
                                Byte[] buf = new Byte[sz];

                                Int32 bytes_from_stream = 0;
                                Int32 total_bytes_read  = 0;
                                Int32 size = sz;
                                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;
                            }
                            //There should be a trailing '0'
                            Int32 l_endChar = (Char)stream.ReadByte();
                        }
                        else
                        {
                            //it must have been a '0', thus no results
                        }
                        break;

                    case 'Z':
                        l_endQuery = true;
                        break;

                    default:
                        throw new NpgsqlException(string.Format("postgresql.fp.protocol {0}", c));
                    }
                }

                if (errorMessage != null)
                {
                    throw new NpgsqlException("postgresql.fp.error" + errorMessage);
                }

                return(result);
            }
        }