protected QueryResultPart GetResultPart(int resultId, int startRow, int countRows) { AssertNotDisposed(); QueryResult table = GetResult(resultId); if (table == null) { throw new DatabaseException("'resultId' invalid."); } int rowEnd = startRow + countRows; if (startRow < 0 || startRow >= table.RowCount || rowEnd > table.RowCount) { throw new DatabaseException("Result part out of range."); } try { int colCount = table.ColumnCount; var block = new QueryResultPart(colCount); for (int r = startRow; r < rowEnd; ++r) { var row = new object[colCount]; 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) { var reference = (IRef)value.Object; clientOb = new StreamableObject(reference.Type, reference.RawSize, reference.Id); } else { clientOb = value.Object; } row[c] = clientOb; } block.AddRow(row); } 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 DatabaseException("Exception while reading results: " + e.Message, e); } }
protected QueryResultPart GetResultPart(int resultId, int startRow, int countRows) { AssertNotDisposed(); var table = GetResult(resultId); if (table == null) { throw new InvalidOperationException(); } int rowEnd = startRow + countRows; if (startRow < 0 || startRow >= table.RowCount || rowEnd > table.RowCount) { throw new InvalidOperationException("Result part out of range."); } try { int colCount = table.ColumnCount; var block = new QueryResultPart(colCount); for (int r = startRow; r < rowEnd; ++r) { var row = new ISqlObject[colCount]; var sizes = new int[colCount]; for (int c = 0; c < colCount; ++c) { var value = table.GetValue(r, c); ISqlObject clientOb = null; if (value.Value is IObjectRef) { var reference = (IObjectRef)value.Value; clientOb = new RemoteObjectRef(reference.ObjectId, reference.Size); } else { clientOb = value.Value; } row[c] = clientOb; sizes[c] = value.Size; } block.AddRow(new QueryResultRow(row, sizes)); } return(block); } catch (Exception) { // TODO: Log a warning ... throw; } }
public void Setup(int id, QueryResultColumn[] columnList, int totalRowCount) { ResultId = id; columns = columnList; resultRowCount = totalRowCount; blockTopRow = -1; resultBlock = null; realIndex = -1; fetchSize = connection.Settings.FetchSize; Closed = false; }
public void Download(int rowIndex, int rowCount) { // If row_count is 0 then we don't need to do anything. if (rowCount == 0) { return; } if (rowIndex + rowCount < 0) { throw new DeveelDbException("Result row index is before the start of the set."); } if (rowIndex < 0) { rowIndex = 0; rowCount = rowCount + rowIndex; } if (rowIndex >= RowCount) { throw new DeveelDbException("Result row index is after the end of the set."); } if (rowIndex + rowCount > RowCount) { rowCount = RowCount - rowIndex; } if (ResultId == -1) { throw new DeveelDbException("Result ID is invalid."); } try { // Request the result via the RowCache. If the information is not found // in the row cache then the request is forwarded onto the database. resultBlock = connection.RowCache.GetResultPart(ResultId, rowIndex, rowCount, ColumnCount, RowCount); // Set the row that's at the top blockTopRow = rowIndex; // Set the number of rows in the block. blockRowCount = rowCount; } catch (DeveelDbException) { throw; } catch (Exception ex) { throw new DeveelDbException("Error while downloading the result data.", ex); } }
private void Dispose(bool disposing) { if (disposing) { try { Close(); } catch (DeveelDbException) { // Ignore // We ignore exceptions because handling cases where the server // connection has broken for many ResultSets would be annoying. } } connection = null; columns = null; resultBlock = null; }
/// <summary> /// Requests a block of parts. /// </summary> /// <param name="resultId"></param> /// <param name="rowIndex"></param> /// <param name="rowCount"></param> /// <param name="colCount"></param> /// <param name="totalRowCount"></param> /// <remarks> /// If the block can be completely retrieved from the cache then it is /// done so. Otherwise, it forwards the request for the rows onto the /// connection object. /// </remarks> /// <returns></returns> public QueryResultPart GetResultPart(int resultId, int rowIndex, int rowCount, int colCount, int totalRowCount) { lock (this) { // What was requested.... int origRowIndex = rowIndex; int origRowCount = rowCount; var cachedRows = new List<CachedRow>(); // The top row that isn't found in the cache. bool foundNotcached = false; // Look for the top row in the block that hasn't been cached for (int r = 0; r < rowCount && !foundNotcached; ++r) { int daRow = rowIndex + r; // Is the row in the cache? var rowRef = new RowRef(resultId, daRow); // Not in cache so mark this as top row not in cache... object rowObj; if (!rowCache.TryGet(rowRef, out rowObj)) { rowIndex = daRow; if (rowIndex + rowCount > totalRowCount) { rowCount = totalRowCount - rowIndex; } foundNotcached = true; } else { var row = (CachedRow) rowObj; cachedRows.Add(row); } } var notCachedRows = new List<CachedRow>(); if (foundNotcached) { // Now work up from the bottom and find row that isn't in cache.... foundNotcached = false; // Look for the bottom row in the block that hasn't been cached for (int r = rowCount - 1; r >= 0 && !foundNotcached; --r) { int daRow = rowIndex + r; // Is the row in the cache? var rowRef = new RowRef(resultId, daRow); // Not in cache so mark this as top row not in cache... object rowObj; if (!rowCache.TryGet(rowRef, out rowObj)) { if (rowIndex == origRowIndex) { rowIndex = rowIndex - (rowCount - (r + 1)); if (rowIndex < 0) { rowCount = rowCount + rowIndex; rowIndex = 0; } } else { rowCount = r + 1; } foundNotcached = true; } else { var row = (CachedRow) rowObj; notCachedRows.Insert(0, row); } } } // Some of it not in the cache... if (foundNotcached) { // Request a part of a result from the server (blocks) QueryResultPart block = connection.RequestResultPart(resultId, rowIndex, rowCount); for (int r = 0; r < rowCount; ++r) { var rowData = new ISqlObject[block.ColumnCount]; var dataSizes = new int[block.ColumnCount]; int theRow = (rowIndex + r); int colSize = 0; var row = block.GetRow(r); for (int c = 0; c < colCount; ++c) { var ob = row.Values[c]; rowData[c] = ob; dataSizes[c] = row.ValueSizes[c]; colSize += row.ValueSizes[c]; } var cachedRow = new CachedRow { ResultId = resultId, Row = theRow, RowData = rowData, Sizes = dataSizes }; // Don't cache if it's over a certain size, if (colSize <= 3200) { rowCache.Set(new RowRef(resultId, theRow), cachedRow); } cachedRows.Add(cachedRow); } } // At this point, the cached rows should be completely in the cache so // retrieve it from the cache. var resultPart = new QueryResultPart(colCount); int low = origRowIndex; int high = origRowIndex + origRowCount; foreach (CachedRow row in cachedRows) { if (row.ResultId != resultId) continue; // Put into the result block if (row.Row >= low && row.Row < high) { var rowArray = new ISqlObject[colCount]; var rowSizes = new int[colCount]; for (int c = 0; c < colCount; ++c) { rowArray[c] = row.RowData[c]; rowSizes[c] = row.Sizes[c]; } resultPart.AddRow(new QueryResultRow(rowArray, rowSizes)); } } foreach (CachedRow row in notCachedRows) { if (row.ResultId != resultId) continue; // Put into the result block if (row.Row >= low && row.Row < high) { var rowArray = new ISqlObject[colCount]; var sizes = new int[colCount]; for (int c = 0; c < colCount; ++c) { rowArray[c] = row.RowData[c]; sizes[c] = row.Sizes[c]; } resultPart.AddRow(new QueryResultRow(rowArray, sizes)); } } // And return the result (phew!) return resultPart; } }
protected QueryResultPart GetResultPart(int resultId, int startRow, int countRows) { AssertNotDisposed(); var table = GetResult(resultId); if (table == null) throw new InvalidOperationException(); int rowEnd = startRow + countRows; if (startRow < 0 || startRow >= table.RowCount || rowEnd > table.RowCount) { throw new InvalidOperationException("Result part out of range."); } try { int colCount = table.ColumnCount; var block = new QueryResultPart(colCount); for (int r = startRow; r < rowEnd; ++r) { var row = new ISqlObject[colCount]; var sizes = new int[colCount]; for (int c = 0; c < colCount; ++c) { var value = table.GetValue(r, c); ISqlObject clientOb = null; if (value.Value is IObjectRef) { var reference = (IObjectRef)value.Value; // TODO: Make a protocol placeholder for the large object ref } else { clientOb = value.Value; } row[c] = clientOb; sizes[c] = value.Size; } block.AddRow(new QueryResultRow(row, sizes)); } return block; } catch (Exception e) { // TODO: Log a warning ... throw; } }
public QueryResultPartResponse(int resultId, QueryResultPart part) { Part = part; ResultId = resultId; }
public void Download(int rowIndex, int rowCount) { // If row_count is 0 then we don't need to do anything. if (rowCount == 0) return; if (rowIndex + rowCount < 0) throw new DeveelDbException("Result row index is before the start of the set."); if (rowIndex < 0) { rowIndex = 0; rowCount = rowCount + rowIndex; } if (rowIndex >= RowCount) throw new DeveelDbException("Result row index is after the end of the set."); if (rowIndex + rowCount > RowCount) rowCount = RowCount - rowIndex; if (ResultId == -1) throw new DeveelDbException("Result ID is invalid."); try { // Request the result via the RowCache. If the information is not found // in the row cache then the request is forwarded onto the database. resultBlock = connection.RowCache.GetResultPart(ResultId, rowIndex, rowCount, ColumnCount, RowCount); // Set the row that's at the top blockTopRow = rowIndex; // Set the number of rows in the block. blockRowCount = rowCount; } catch(DeveelDbException) { throw; } catch (Exception ex) { throw new DeveelDbException("Error while downloading the result data.", ex); } }
protected QueryResultPart GetResultPart(int resultId, int startRow, int countRows) { AssertNotDisposed(); QueryResult table = GetResult(resultId); if (table == null) throw new DatabaseException("'resultId' invalid."); int rowEnd = startRow + countRows; if (startRow < 0 || startRow >= table.RowCount || rowEnd > table.RowCount) { throw new DatabaseException("Result part out of range."); } try { int colCount = table.ColumnCount; var block = new QueryResultPart(colCount); for (int r = startRow; r < rowEnd; ++r) { var row = new object[colCount]; 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) { var reference = (IRef) value.Object; clientOb = new StreamableObject(reference.Type, reference.RawSize, reference.Id); } else { clientOb = value.Object; } row[c] = clientOb; } block.AddRow(row); } 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 DatabaseException("Exception while reading results: " + e.Message, e); } }