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