Esempio n. 1
0
        private static DateTimeOffset ConvertToDateTimeOffset(UTF8Buffer srcVal, SFDataType srcType)
        {
            switch (srcType)
            {
            case SFDataType.TIMESTAMP_TZ:
                int spaceIndex = Array.IndexOf <byte>(srcVal.Buffer, (byte)' ', srcVal.offset, srcVal.length);;
                if (spaceIndex == -1)
                {
                    throw new SnowflakeDbException(SFError.INTERNAL_ERROR,
                                                   $"Invalid timestamp_tz value: {srcVal}");
                }
                else
                {
                    spaceIndex -= srcVal.offset;
                    Tuple <long, long> secAndNsecTZ = ExtractTimestamp(new UTF8Buffer(srcVal.Buffer, srcVal.offset, spaceIndex));

                    int      offset         = FastParser.FastParseInt32(srcVal.Buffer, srcVal.offset + spaceIndex + 1, srcVal.length - spaceIndex - 1);
                    TimeSpan offSetTimespan = new TimeSpan((offset - 1440) / 60, 0, 0);
                    return(new DateTimeOffset(UnixEpoch.Ticks +
                                              (secAndNsecTZ.Item1 * 1000 * 1000 * 1000 + secAndNsecTZ.Item2) / 100, TimeSpan.Zero).ToOffset(offSetTimespan));
                }

            case SFDataType.TIMESTAMP_LTZ:
                Tuple <long, long> secAndNsecLTZ = ExtractTimestamp(srcVal);

                return(new DateTimeOffset(UnixEpoch.Ticks +
                                          (secAndNsecLTZ.Item1 * 1000 * 1000 * 1000 + secAndNsecLTZ.Item2) / 100, TimeSpan.Zero).ToLocalTime());

            default:
                throw new SnowflakeDbException(SFError.INVALID_DATA_CONVERSION, srcVal,
                                               srcType, typeof(DateTimeOffset).ToString());
            }
        }
Esempio n. 2
0
        private static DateTime ConvertToDateTime(UTF8Buffer srcVal, SFDataType srcType)
        {
            switch (srcType)
            {
            case SFDataType.DATE:
                long srcValLong = FastParser.FastParseInt64(srcVal.Buffer, srcVal.offset, srcVal.length);
                return(UnixEpoch.AddDays(srcValLong));

            case SFDataType.TIME:
            case SFDataType.TIMESTAMP_NTZ:

                Tuple <long, long> secAndNsec = ExtractTimestamp(srcVal);
                var tickDiff = secAndNsec.Item1 * 10000000L + secAndNsec.Item2 / 100L;
                return(UnixEpoch.AddTicks(tickDiff));

            default:
                throw new SnowflakeDbException(SFError.INVALID_DATA_CONVERSION, srcVal, srcType, typeof(DateTime));
            }
        }
Esempio n. 3
0
        private static Tuple <long, long> ExtractTimestamp(UTF8Buffer srcVal)
        {
            int dotIndex = Array.IndexOf <byte>(srcVal.Buffer, (byte)'.', srcVal.offset, srcVal.length);

            if (dotIndex == -1)
            {
                return(Tuple.Create(FastParser.FastParseInt64(srcVal.Buffer, srcVal.offset, srcVal.length), (long)0));
            }
            else
            {
                dotIndex -= srcVal.offset;
                var intPart           = FastParser.FastParseInt64(srcVal.Buffer, srcVal.offset, dotIndex);
                var decimalPartLength = srcVal.length - dotIndex - 1;
                var decimalPart       = FastParser.FastParseInt64(srcVal.Buffer, srcVal.offset + dotIndex + 1, decimalPartLength);
                // If the decimal part contained less than nine characters, we must convert the value to nanoseconds by
                // multiplying by 10^[precision difference].
                if (decimalPartLength < 9 && decimalPartLength > 0)
                {
                    decimalPart *= powersOf10[9 - decimalPartLength];
                }

                return(Tuple.Create(intPart, decimalPart));
            }
        }
Esempio n. 4
0
        internal static object ConvertToCSharpVal(UTF8Buffer srcVal, SFDataType srcType, Type destType)
        {
            if (srcVal == null)
            {
                return(DBNull.Value);
            }

            try
            {
                // The most common conversions are checked first for maximum performance
                if (destType == typeof(Int64))
                {
                    return(FastParser.FastParseInt64(srcVal.Buffer, srcVal.offset, srcVal.length));
                }
                else if (destType == typeof(Int32))
                {
                    return(FastParser.FastParseInt32(srcVal.Buffer, srcVal.offset, srcVal.length));
                }
                else if (destType == typeof(decimal))
                {
                    return(FastParser.FastParseDecimal(srcVal.Buffer, srcVal.offset, srcVal.length));
                }
                else if (destType == typeof(string))
                {
                    return(srcVal.ToString());
                }
                else if (destType == typeof(DateTime))
                {
                    return(ConvertToDateTime(srcVal, srcType));
                }
                else if (destType == typeof(DateTimeOffset))
                {
                    return(ConvertToDateTimeOffset(srcVal, srcType));
                }
                else if (destType == typeof(Boolean))
                {
                    var val = srcVal.Buffer[srcVal.offset];
                    return(val == '1' || val == 't' || val == 'T');
                }
                else if (destType == typeof(byte[]))
                {
                    return(srcType == SFDataType.BINARY ?
                           HexToBytes(srcVal.ToString()) : srcVal.GetBytes());
                }
                else if (destType == typeof(Int16))
                {
                    // Use checked keyword to make sure we generate an OverflowException if conversion fails
                    int result = FastParser.FastParseInt32(srcVal.Buffer, srcVal.offset, srcVal.length);
                    return(checked ((Int16)result));
                }
                else if (destType == typeof(byte))
                {
                    // Use checked keyword to make sure we generate an OverflowException if conversion fails
                    int result = FastParser.FastParseInt32(srcVal.Buffer, srcVal.offset, srcVal.length);
                    return(checked ((byte)result));
                }
                else if (destType == typeof(double))
                {
                    return(Convert.ToDouble(srcVal.ToString(), CultureInfo.InvariantCulture));
                }
                else if (destType == typeof(float))
                {
                    return(Convert.ToSingle(srcVal.ToString(), CultureInfo.InvariantCulture));
                }
                else if (destType == typeof(Guid))
                {
                    return(new Guid(srcVal.ToString()));
                }
                else if (destType == typeof(char[]))
                {
                    byte[] data = srcType == SFDataType.BINARY ?
                                  HexToBytes(srcVal.ToString()) : srcVal.GetBytes();
                    return(Encoding.UTF8.GetString(data).ToCharArray());
                }
                else
                {
                    throw new SnowflakeDbException(SFError.INTERNAL_ERROR, "Invalid destination type.");
                }
            }
            catch (OverflowException)
            {
                throw new OverflowException($"Error converting '{srcVal} to {destType.Name}'. Use GetString() to handle very large values");
            }
        }