示例#1
0
        internal static Type GetFieldTypeFromSqliteType(DqliteTypes dqliteType)
        {
            switch (dqliteType)
            {
            case DqliteTypes.Integer:
                return(typeof(long));

            case DqliteTypes.Float:
                return(typeof(double));

            case DqliteTypes.Text:
                return(typeof(string));

            case DqliteTypes.Boolean:
                return(typeof(bool));

            case DqliteTypes.ISO8601:
                //case DqliteTypes.UnixTime:
                return(typeof(DateTime));

            default:
                Debug.Assert(
                    dqliteType == DqliteTypes.Blob || dqliteType == DqliteTypes.Null,
                    "Unexpected column type: " + dqliteType);
                return(typeof(byte[]));
            }
        }
        public static DqliteDataRecord ParseDataRecordResponse(ResponseTypes type, int size, Memory <byte> data)
        {
            ThrowOnFailure(type, size, data);
            if (type != ResponseTypes.ResponseRows)
            {
                throw new InvalidOperationException($"Invalid response: expected {ResponseTypes.ResponseRows}, actually {type}");
            }

            var span = data.Span;

            var columns = new string[span.ReadUInt64()];
            var types   = new List <DqliteTypes[]>();
            var values  = new List <object[]>();

            for (var i = 0; i < columns.Length; ++i)
            {
                columns[i] = span.ReadString();
            }

            while (span.Length > 0)
            {
                var rowTypes  = new DqliteTypes[columns.Length];
                var rowValues = new object[columns.Length];

                var headerBits = rowTypes.Length * 4;
                var padBits    = 0;
                if (headerBits % 64 != 0)
                {
                    padBits = 64 - (headerBits % 64);
                }

                var headerSize = (headerBits + padBits) / 64 * 8;
                for (var i = 0; i < headerSize; ++i)
                {
                    var slot = span.ReadByte();
                    if (slot == 0xee)
                    {
                        // More rows are available.
                        return(new DqliteDataRecord(columns, types, values, true));
                    }
                    else if (slot == 0xff)
                    {
                        return(new DqliteDataRecord(columns, types, values, false));
                    }

                    var index = i * 2;
                    if (index >= rowTypes.Length)
                    {
                        // This is padding.
                        continue;
                    }
                    rowTypes[index] = (DqliteTypes)(slot & 0x0f);

                    if (++index >= rowTypes.Length)
                    {
                        // This is padding.
                        continue;
                    }
                    rowTypes[index] = (DqliteTypes)(slot >> 4);
                }

                for (var i = 0; i < rowTypes.Length; ++i)
                {
                    switch (rowTypes[i])
                    {
                    case DqliteTypes.Integer:
                        rowValues[i] = span.ReadInt64();
                        break;

                    case DqliteTypes.Float:
                        rowValues[i] = span.ReadDouble();
                        break;

                    case DqliteTypes.Blob:
                        rowValues[i] = span.ReadBlob();
                        break;

                    case DqliteTypes.Text:
                        rowValues[i] = span.ReadString();
                        break;

                    case DqliteTypes.Null:
                        span.ReadUInt64();
                        rowValues[i] = null;
                        break;

                    /*
                     * case DqliteTypes.UnixTime:
                     *  //TODO
                     *  rowValues[i] = span.ReadInt64();
                     *  break;
                     */
                    case DqliteTypes.ISO8601:
                    {
                        var value = span.ReadString();
                        if (string.IsNullOrEmpty(value))
                        {
                            rowValues[i] = DateTime.MinValue;
                        }

                        rowValues[i] = DateTime.Parse(value);
                        break;
                    }

                    case DqliteTypes.Boolean:
                        rowValues[i] = span.ReadUInt64() != 0;
                        break;

                    default:
                        throw new DqliteException(0, "Unknown type");
                    }
                }

                types.Add(rowTypes);
                values.Add(rowValues);
            }

            throw new EndOfStreamException();
        }