/// <summary> /// Responds with a part of the result set of a query made via the /// <see cref="ProtocolConstants.Query"/> Query. /// </summary> /// <param name="dispatchId">The number we need to respond with.</param> /// <param name="command"></param> /// <returns></returns> private byte[] ResultSection(int dispatchId, byte[] command) { int resultId = ByteBuffer.ReadInt4(command, 8); int rowNumber = ByteBuffer.ReadInt4(command, 12); int rowCount = ByteBuffer.ReadInt4(command, 16); try { // Get the result part... ResultPart block = dbInterface.GetResultPart(resultId, rowNumber, rowCount); MemoryStream output = new MemoryStream(); BinaryWriter writer = new BinaryWriter(output, Encoding.Unicode); writer.Write(dispatchId); writer.Write(ProtocolConstants.Success); // Send the contents of the result set. // HACK - Work out column count by dividing number of entries in block // by number of rows. int colCount = block.Count / rowCount; writer.Write(colCount); int bsize = block.Count; for (int index = 0; index < bsize; ++index) { ObjectTransfer.WriteTo(writer, block[index]); } writer.Flush(); return(output.ToArray()); } catch (DataException e) { return(Exception(dispatchId, e)); } }
/// <inheritdoc/> public ResultPart GetResultPart(int resultId, int startRow, int countRows) { try { // Get the first few rows of the result.. int dispatchId = connectionThread.GetResultPart(resultId, startRow, countRows); // Get the response ServerCommand command = connectionThread.ReceiveCommand(DeveelDbConnection.QueryTimeout, dispatchId); // If command == null then we timed output if (command == null) throw new DataException("Downloading result part timed output after " + DeveelDbConnection.QueryTimeout + " seconds."); // Wrap around a DataInputStream BinaryReader reader = new BinaryReader(command.GetInputStream()); int status = reader.ReadInt32(); if (status == ProtocolConstants.Success) { // Return the contents of the response. int colCount = reader.ReadInt32(); int size = countRows * colCount; ResultPart list = new ResultPart(size); for (int i = 0; i < size; ++i) { list.Add(ObjectTransfer.ReadFrom(reader)); } return list; } if (status == ProtocolConstants.Exception) { int dbCode = reader.ReadInt32(); string message = reader.ReadString(); string stackTrace = reader.ReadString(); throw new DbDataException(message, message, dbCode, stackTrace); } throw new DataException("Illegal response code from server."); } catch (IOException e) { LogException(e); throw new DataException("IO Error: " + e.Message); } }
/// <inheritdoc/> public ResultPart GetResultPart(int resultId, int startRow, int countRows) { CheckNotDisposed(); ResultSetInfo table = GetResultSet(resultId); if (table == null) throw new DbDataException("'resultId' invalid.", null, 4, (Exception) null); int rowEnd = startRow + countRows; if (startRow < 0 || startRow >= table.RowCount || rowEnd > table.RowCount) { throw new DbDataException("Result part out of range.", null, 4, (Exception) null); } try { int colCount = table.ColumnCount; ResultPart block = new ResultPart(countRows*colCount); for (int r = startRow; r < rowEnd; ++r) { for (int c = 0; c < colCount; ++c) { TObject value = table.GetCellContents(c, r); // If this is a IRef, we must assign it a streamable object // id that the client can use to access the large object. object clientOb; if (value.Object is IRef) { IRef reference = (IRef) value.Object; clientOb = new StreamableObject(reference.Type, reference.RawSize, reference.Id); } else { clientOb = value.Object; } block.Add(clientOb); } } return block; } catch (Exception e) { Logger.Warning(this, e); // If an exception was generated while getting the cell contents, then // throw an DataException. throw new DbDataException("Exception while reading results: " + e.Message, e.Message, 4, e); } }