Ejemplo n.º 1
0
        private static DataType GetPropertyDataType(LazyStringValue docId, OlapColumn prop, ref IList data)
        {
            DataType propType;

            switch (prop.Type & BlittableJsonReaderBase.TypesMask)
            {
            case BlittableJsonToken.Integer:
                propType = DataType.Int64;
                data ??= new List <long>();
                break;

            case BlittableJsonToken.LazyNumber:
                var lnv = (LazyNumberValue)prop.Value;
                if (lnv.TryParseULong(out var ulongValue))
                {
                    prop.Value = ulongValue;
                    propType   = DataType.Int64;
                    data ??= new List <long>();
                }
                else if (lnv.TryParseDecimal(out var decimalValue))
                {
                    prop.Value = decimalValue;
                    propType   = DataType.Decimal;
                    data ??= new List <decimal>();
                }
                else
                {
                    prop.Value = (double)lnv;
                    propType   = DataType.Double;
                    data ??= new List <double>();
                }
                break;

            case BlittableJsonToken.CompressedString:
            case BlittableJsonToken.String:
                var str = prop.Value.ToString();
                if (TryParseDate(str, out var dto))
                {
                    propType = DataType.DateTimeOffset;
                    data ??= new List <DateTimeOffset>();
                    prop.Value = dto;
                    break;
                }
                if (TryParseTimeSpan(str, out var ts))
                {
                    propType = DataType.TimeSpan;
                    data ??= new List <TimeSpan>();
                    prop.Value = ts;
                    break;
                }
                propType = DataType.String;
                data ??= new List <string>();
                break;

            case BlittableJsonToken.Boolean:
                propType = DataType.Boolean;
                data ??= new List <bool>();
                break;

            case BlittableJsonToken.StartObject:
                propType = GetTypeFromObject(docId, prop, ref data);
                break;

            default:
                throw new NotSupportedException($"Unsupported {nameof(BlittableJsonToken)} '{prop.Type}'. " +
                                                $"On document '{docId}', property '{prop.Name}'");
            }

            return(propType);
        }
Ejemplo n.º 2
0
        private static DataType GetTypeFromObject(LazyStringValue docId, OlapColumn prop, ref IList data)
        {
            using (var objectValue = (BlittableJsonReaderObject)prop.Value)
            {
                if (objectValue.Count < 2 || objectValue.TryGetMember(nameof(SqlDocumentTransformer.VarcharFunctionCall.Type), out object dbType) == false ||
                    objectValue.TryGetMember(nameof(SqlDocumentTransformer.VarcharFunctionCall.Value), out object fieldValue) == false)
                {
                    prop.Value = objectValue.ToString();
                    data ??= new List <string>();
                    return(DataType.String);
                }

                DataType propType;
                object   value;
                var      type = (DbType)Enum.Parse(typeof(DbType), dbType.ToString(), ignoreCase: true);

                switch (type)
                {
                case DbType.Byte:
                    value    = Convert.ToByte(fieldValue);
                    propType = DataType.Byte;
                    data ??= new List <byte>();
                    break;

                case DbType.SByte:
                    value    = Convert.ToSByte(fieldValue);
                    propType = DataType.SignedByte;
                    data ??= new List <sbyte>();
                    break;

                case DbType.Int16:
                    value    = Convert.ToInt16(fieldValue);
                    propType = DataType.Short;
                    data ??= new List <short>();
                    break;

                case DbType.Int32:
                    value    = Convert.ToInt32(fieldValue);
                    propType = DataType.Int32;
                    data ??= new List <int>();
                    break;

                case DbType.Int64:
                    value    = Convert.ToInt64(fieldValue);
                    propType = DataType.Int64;
                    data ??= new List <long>();
                    break;

                case DbType.UInt16:
                    value    = Convert.ToUInt16(fieldValue);
                    propType = DataType.UnsignedInt16;
                    data ??= new List <ushort>();
                    break;

                case DbType.UInt32:
                    value    = Convert.ToUInt32(fieldValue);
                    propType = DataType.UnsignedInt32;
                    data ??= new List <uint>();
                    break;

                case DbType.UInt64:
                    value    = Convert.ToUInt64(fieldValue);
                    propType = DataType.UnsignedInt64;
                    data ??= new List <ulong>();
                    break;

                case DbType.Single:
                    value    = Convert.ToSingle(fieldValue);
                    propType = DataType.Float;
                    data ??= new List <float>();
                    break;

                case DbType.Double:
                    value    = Convert.ToDouble(fieldValue);
                    propType = DataType.Double;
                    data ??= new List <double>();
                    break;

                case DbType.Decimal:
                    value    = Convert.ToDecimal(fieldValue);
                    propType = DataType.Decimal;
                    data ??= new List <decimal>();
                    break;

                default:
                    throw new NotSupportedException($"Unsupported type '{dbType}' in object '{prop.Name}', On document '{docId}'");
                }

                prop.Value = value;
                return(propType);
            }
        }
Ejemplo n.º 3
0
        private void AddProperty(LazyStringValue docId, OlapColumn prop)
        {
            var propName = prop.Name;

            var newField = _dataTypes.TryGetValue(propName, out var dataType) == false;

            _group.Data.TryGetValue(propName, out var data);

            if (prop.Type == BlittableJsonToken.Null)
            {
                if (newField)
                {
                    UpdateField(DataType.Unspecified, propName, data, _group);
                }
                else
                {
                    AddDefaultData(data, dataType, 1);
                }
                return;
            }

            var propType = GetPropertyDataType(docId, prop, ref data);

            if (newField)
            {
                UpdateField(dataType = propType, propName, data, _group);
            }

            else if (dataType == DataType.Unspecified)
            {
                // existing field that had no values, until now
                // need to change the field type and add default values to fields' data

                Debug.Assert(data.Count == 0, "Invalid data. Data type is 'Unspecified', but data.Count = " + data.Count);

                UpdateField(dataType = propType, propName, data, _group);
            }

            else if (propType != dataType)
            {
                // data type change

                if (TryChangeDataType(dataType, propType, data, out data))
                {
                    // change previous data from 'long' to 'double' / 'decimal'
                    // or from 'decimal' to 'double'
                    UpdateField(dataType = propType, propName, data, _group, addDefaultData: false);
                }

                else if (TryChangeValueType(dataType, propType, prop.Value, out var newValue))
                {
                    // change current value from 'long' to 'double' / 'decimal'
                    // or from 'decimal' to 'double'
                    prop.Value = newValue;
                }
            }

            try
            {
                AddNewValue(data, dataType, prop.Value);
            }
            catch (Exception e)
            {
                throw new InvalidOperationException($"Failed to add value '{prop.Value}' to DataField of type '{dataType}'. " +
                                                    $"On document '{docId}', property '{prop.Name}'", e);
            }
        }