/// <summary> /// Loads a sparse vector. /// </summary> /// <param name="sparseVector">The sparse vector.</param> internal static void Load(SparseVector sparseVector) { var vectorOffset = sparseVector.ParentRecord.SlotOffset + sparseVector.RecordOffset; sparseVector.ComplexHeader = BitConverter.ToInt16(sparseVector.Data, 0); sparseVector.Mark("ComplexHeaderDescription", vectorOffset, sizeof(short)); sparseVector.ColCount = BitConverter.ToInt16(sparseVector.Data, 2); sparseVector.Mark("ColCount", vectorOffset + SparseVector.ColCountOffset, sizeof(short)); sparseVector.Columns = new ushort[sparseVector.ColCount]; sparseVector.Mark("ColumnsDescription", vectorOffset + SparseVector.ColumnsOffset, sparseVector.ColCount * sizeof(short)); sparseVector.Offset = new ushort[sparseVector.ColCount]; sparseVector.Mark("OffsetsDescription", vectorOffset + SparseVector.ColumnsOffset + sparseVector.ColCount * sizeof(short), sparseVector.ColCount * sizeof(short)); var previousOffset = 4 + (sparseVector.ColCount * 4); for (var i = 0; i < sparseVector.ColCount; i++) { sparseVector.Columns[i] = BitConverter.ToUInt16(sparseVector.Data, 4 + (i * 2)); sparseVector.Offset[i] = BitConverter.ToUInt16(sparseVector.Data, (4 + sparseVector.ColCount * 2) + (i * 2)); var columnData = new byte[sparseVector.Offset[i] - previousOffset]; Array.Copy(sparseVector.Data, previousOffset, columnData, 0, sparseVector.Offset[i] - previousOffset); var column = sparseVector.Structure.Columns.Find(delegate(Column col) { return(col.ColumnId == sparseVector.Columns[i]); }); var field = new RecordField(column); field.Data = columnData; field.Sparse = true; field.Offset = sparseVector.Offset[i]; field.Length = sparseVector.Offset[i] - previousOffset; field.Mark("Value", vectorOffset + previousOffset, field.Length); sparseVector.ParentRecord.Mark("FieldsArray", field.Name + " (Sparse)", sparseVector.ParentRecord.Fields.Count); previousOffset = sparseVector.Offset[i]; sparseVector.ParentRecord.Fields.Add(field); } }
/// <summary> /// Loads a LOB field. /// </summary> /// <param name="field">The field.</param> /// <param name="data">The data.</param> /// <param name="offset">The offset.</param> public static void LoadLobField(RecordField field, byte[] data, int offset) { field.Mark("BlobInlineRoot"); // First byte gives the Blob field type switch ((BlobFieldType)data[0]) { case BlobFieldType.LobPointer: field.BlobInlineRoot = new PointerField(data, offset); break; case BlobFieldType.LobRoot: field.BlobInlineRoot = new RootField(data, offset); break; case BlobFieldType.RowOverflow: field.BlobInlineRoot = new OverflowField(data, offset); break; } }
/// <summary> /// Loads the column values. /// </summary> /// <param name="dataRecord">The data record.</param> /// <returns></returns> private static void LoadColumnValues(DataRecord dataRecord) { RecordField field; var columnValues = new List <RecordField>(); var index = 0; foreach (var column in dataRecord.Structure.Columns) { if (!column.Sparse) { field = new RecordField(column); short length = 0; ushort offset = 0; var isLob = false; byte[] data = null; ushort variableIndex = 0; if (column.Sparse) { // Can't remember what needs to happen here, will fix when I revisit the sparse column support } else if (column.LeafOffset >= 0 && column.LeafOffset < Page.Size) { // Fixed length field // Fixed offset given by the column leaf offset field in sys.columns offset = (ushort)column.LeafOffset; // Length fixed from data type/data length length = column.DataLength; data = new byte[length]; Array.Copy(dataRecord.Page.PageData, column.LeafOffset + dataRecord.SlotOffset, data, 0, length); } else if (dataRecord.HasVariableLengthColumns && dataRecord.HasNullBitmap && !column.Dropped && (column.ColumnId < 0 || !dataRecord.NullBitmapValue(column))) { // Variable Length fields // Use the leaf offset to get the variable length column ordinal variableIndex = (ushort)((column.LeafOffset * -1) - 1); if (variableIndex == 0) { // If it's position 0 the start of the data will be at the variable length data offset... offset = dataRecord.VariableLengthDataOffset; } else { // ...else use the end offset of the previous column as the start of this one offset = DecodeOffset(dataRecord.ColOffsetArray[variableIndex - 1]); } if (variableIndex < dataRecord.ColOffsetArray.Length) { isLob = (dataRecord.ColOffsetArray[variableIndex] & 0x8000) == 0x8000; length = (short)(DecodeOffset(dataRecord.ColOffsetArray[variableIndex]) - offset); } else { isLob = false; length = 0; } data = new byte[length]; Array.Copy(dataRecord.Page.PageData, dataRecord.SlotOffset + offset, data, 0, length); } field.Offset = offset; field.Length = length; field.Data = data; field.VariableOffset = variableIndex; if (isLob) { LoadLobField(field, data, dataRecord.SlotOffset + offset); } else { field.Mark("Value", dataRecord.SlotOffset + field.Offset, field.Length); } dataRecord.Mark("FieldsArray", field.Name, index); index++; columnValues.Add(field); } } dataRecord.Fields.AddRange(columnValues); }
private static void LoadColumnValues(IndexRecord record) { RecordField field; var columnValues = new List <RecordField>(); var index = 0; foreach (IndexColumn indexCol in (record.Structure as IndexStructure).Columns) { var processKeyColumn = !indexCol.Key || (record.IncludeKey && indexCol.Key); var processIncludesColumn = !indexCol.IncludedColumn || (indexCol.IncludedColumn && record.IsIndexType(IndexTypes.Leaf)); if (processKeyColumn & processIncludesColumn) { field = new RecordField(indexCol); var length = 0; var offset = 0; byte[] data = null; var variableIndex = 0; if (indexCol.LeafOffset >= 0) { // Fixed length field offset = indexCol.LeafOffset; length = indexCol.DataLength; data = new byte[length]; Array.Copy(record.Page.PageData, indexCol.LeafOffset + record.SlotOffset, data, 0, length); } else if (record.HasVariableLengthColumns) { //Variable length field variableIndex = (indexCol.LeafOffset * -1) - 1; if (variableIndex == 0) { offset = record.VariableLengthDataOffset; } else { offset = record.ColOffsetArray[variableIndex - 1]; } if (variableIndex >= record.ColOffsetArray.Length) { length = 0; } else { length = record.ColOffsetArray[variableIndex] - offset; } data = new byte[length]; Array.Copy(record.Page.PageData, offset + record.SlotOffset, data, 0, length); } field.Offset = offset; field.Length = length; field.Data = data; field.VariableOffset = variableIndex; field.Mark("Value", record.SlotOffset + field.Offset, field.Length); record.Mark("FieldsArray", field.Name, index); index++; columnValues.Add(field); } } record.Fields.AddRange(columnValues); }