private ODocument ExecuteOperationInternal(IOperation operation)
        {
            try
            {
                if (_networkStream == null)
                    Reconnect();

                var req = new Request(this);
                req.SetSessionId(SessionId);

                Request request = operation.Request(req);
                byte[] buffer;

                foreach (RequestDataItem item in request.DataItems)
                {
                    switch (item.Type)
                    {
                        case "byte":
                        case "short":
                        case "int":
                        case "long":
                            Send(item.Data);
                            break;
                        case "record":
                            buffer = new byte[2 + item.Data.Length];
                            Buffer.BlockCopy(BinarySerializer.ToArray(item.Data.Length), 0, buffer, 0, 2);
                            Buffer.BlockCopy(item.Data, 0, buffer, 2, item.Data.Length);
                            Send(buffer);
                            break;
                        case "bytes":
                        case "string":
                        case "strings":
                            Send(BinarySerializer.ToArray(item.Data.Length));
                            Send(item.Data);
                            break;
                        default:
                            break;
                    }
                }

                _networkStream.Flush();

                if (request.OperationMode != OperationMode.Synchronous)
                    return null;

                Response response = new Response(this);
                response.Receive();
                return ((IOperation)operation).Response(response);
            }
            catch (IOException)
            {
                Destroy();
                throw;
            }
        }
示例#2
0
        public override ODocument Response(Response response)
        {
            ODocument responseDocument = new ODocument();

            if (response == null)
            {
                return responseDocument;
            }

            var reader = response.Reader;
            if (response.Connection.ProtocolVersion > 26 && response.Connection.UseTokenBasedSession)
                ReadToken(reader);

            // operation specific fields
            PayloadStatus payloadStatus = (PayloadStatus)reader.ReadByte();

            responseDocument.SetField("PayloadStatus", payloadStatus);

            if (OperationMode == OperationMode.Asynchronous)
            {
                List<ODocument> documents = new List<ODocument>();

                while (payloadStatus != PayloadStatus.NoRemainingRecords)
                {
                    ODocument document = ParseDocument(reader);

                    switch (payloadStatus)
                    {
                        case PayloadStatus.ResultSet:
                            documents.Add(document);
                            break;
                        case PayloadStatus.PreFetched:
                            //client cache
                            response.Connection.Database.ClientCache[document.ORID] = document;
                            break;
                        default:
                            break;
                    }

                    payloadStatus = (PayloadStatus)reader.ReadByte();
                }

                responseDocument.SetField("Content", documents);
            }
            else
            {
                int contentLength;

                switch (payloadStatus)
                {
                    case PayloadStatus.NullResult: // 'n'
                        // nothing to do
                        break;
                    case PayloadStatus.SingleRecord: // 'r'
                        ODocument document = ParseDocument(reader);
                        responseDocument.SetField("Content", document);
                        break;
                    case PayloadStatus.SerializedResult: // 'a'
                        contentLength = reader.ReadInt32EndianAware();
                        string serialized = System.Text.Encoding.Default.GetString(reader.ReadBytes(contentLength));
                        responseDocument.SetField("Content", serialized);
                        break;
                    case PayloadStatus.RecordCollection: // 'l'
                        List<ODocument> documents = new List<ODocument>();

                        int recordsCount = reader.ReadInt32EndianAware();

                        for (int i = 0; i < recordsCount; i++)
                        {
                            documents.Add(ParseDocument(reader));
                        }

                        responseDocument.SetField("Content", documents);
                        break;
                    default:
                        break;
                }

                if (OClient.ProtocolVersion >= 17)
                {
                    //Load the fetched records in cache
                    while ((payloadStatus = (PayloadStatus)reader.ReadByte()) != PayloadStatus.NoRemainingRecords)
                    {
                        ODocument document = ParseDocument(reader);
                        if (document != null && payloadStatus == PayloadStatus.PreFetched)
                        {
                            //Put in the client local cache
                            response.Connection.Database.ClientCache[document.ORID] = document;
                        }
                    }
                }
            }

            return responseDocument;
        }
示例#3
0
        public ODocument Response(Response response)
        {
            // start from this position since standard fields (status, session ID) has been already parsed
            int offset = 5;
            ODocument responseDocument = new ODocument();
            
            if (response == null)
            {
                return responseDocument;
            }

            // operation specific fields
            PayloadStatus payloadStatus = (PayloadStatus)BinarySerializer.ToByte(response.Data.Skip(offset).Take(1).ToArray());
            offset += 1;

            responseDocument.SetField("PayloadStatus", payloadStatus);

            if (OperationMode == OperationMode.Asynchronous)
            {
                List<ODocument> documents = new List<ODocument>();

                while (payloadStatus != PayloadStatus.NoRemainingRecords)
                {
                    ODocument document = ParseDocument(ref offset, response.Data);

                    switch (payloadStatus)
                    {
                        case PayloadStatus.ResultSet:
                            documents.Add(document);
                            break;
                        case PayloadStatus.PreFetched:
                            // TODO: client cache
                            documents.Add(document);
                            break;
                        default:
                            break;
                    }

                    payloadStatus = (PayloadStatus)BinarySerializer.ToByte(response.Data.Skip(offset).Take(1).ToArray());
                    offset += 1;
                }

                responseDocument.SetField("Content", documents);
            }
            else
            {
                int contentLength;

                switch (payloadStatus)
                {
                    case PayloadStatus.NullResult: // 'n'
                        // nothing to do
                        break;
                    case PayloadStatus.SingleRecord: // 'r'
                        ODocument document = ParseDocument(ref offset, response.Data);
                        responseDocument.SetField("Content", document);
                        break;
                    case PayloadStatus.SerializedResult: // 'a'
                        // TODO: how to parse result - string?
                        contentLength = BinarySerializer.ToInt(response.Data.Skip(offset).Take(4).ToArray());
                        offset += 4;
                        string serialized = BinarySerializer.ToString(response.Data.Skip(offset).Take(contentLength).ToArray());
                        offset += contentLength;

                        responseDocument.SetField("Content", serialized);
                        break;
                    case PayloadStatus.RecordCollection: // 'l'
                        int recordsCount = BinarySerializer.ToInt(response.Data.Skip(offset).Take(4).ToArray());
                        offset += 4;

                        List<ODocument> documents = new List<ODocument>();

                        for (int i = 0; i < recordsCount; i++)
                        {
                            documents.Add(ParseDocument(ref offset, response.Data));
                        }

                        responseDocument.SetField("Content", documents);
                        break;
                    default:
                        break;
                }
            }

            return responseDocument;
        }
示例#4
0
 public override bool Read()
 {
     if (!_isExecuted)
     {
         _isExecuted = true;
         _operation = CreateOperation();
         _command.Database.Connection.ExecuteOperation(_operation, r => _response = r);
         _reader = new OResponseReader(this, _response, _command.IsIdempotent ? OperationMode.Asynchronous : OperationMode.Synchronous);
         _enumerator = _reader.GetEnumerator();
     }
     return _enumerator.MoveNext();
 }
        internal ODocument ExecuteOperation(IOperation operation)
        {
            Request request = operation.Request(SessionId);
            byte[] buffer;

            foreach (RequestDataItem item in request.DataItems)
            {
                switch (item.Type)
                {
                    case "byte":
                    case "short":
                    case "int":
                    case "long":
                        Send(item.Data);
                        break;
                    case "record":
                        buffer = new byte[2 + item.Data.Length];
                        Buffer.BlockCopy(BinarySerializer.ToArray(item.Data.Length), 0, buffer, 0, 2);
                        Buffer.BlockCopy(item.Data, 0, buffer, 2, item.Data.Length);
                        Send(buffer);
                        break;
                    case "bytes":
                    case "string":
                    case "strings":
                        //buffer = new byte[4 + item.Data.Length];
                        //Buffer.BlockCopy(BinarySerializer.ToArray(item.Data.Length), 0, buffer, 0, 4);
                        //Buffer.BlockCopy(item.Data, 0, buffer, 4, item.Data.Length);
                        //Send(buffer);

                        Send(BinarySerializer.ToArray(item.Data.Length));
                        Send(item.Data);
                        break;
                    default:
                        break;
                }
            }

            _networkStream.Flush();

            if (request.OperationMode == OperationMode.Synchronous)
            {
                try
                {
                    Response response = new Response(this);

                    response.Receive();

                    return ((IOperation)operation).Response(response);
                }
                catch (Exception )
                {
                    //reset connection as the socket may contains unread data and is considered unstable
                    Reconnect();
                    throw;
                }
            }
            else
            {
                return null;
            }
        }