Beispiel #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());
            }
        }
Beispiel #2
0
        internal object GetValue(int columnIndex)
        {
            UTF8Buffer val   = getObjectInternal(columnIndex);
            var        types = sfResultSetMetaData.GetTypesByIndex(columnIndex);

            return(SFDataConverter.ConvertToCSharpVal(val, types.Item1, types.Item2));
        }
Beispiel #3
0
        // Method with the same signature as before the performance work
        // Used by unit tests only
        internal static object ConvertToCSharpVal(string srcVal, SFDataType srcType, Type destType)
        {
            // Create an UTF8Buffer with an offset to get better testing
            byte[] b1 = Encoding.UTF8.GetBytes(srcVal);
            byte[] b2 = new byte[b1.Length + 100];
            Array.Copy(b1, 0, b2, 100, b1.Length);
            var v = new UTF8Buffer(b2, 100, b1.Length);

            return(ConvertToCSharpVal(v, srcType, destType));
        }
Beispiel #4
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));
            }
        }
Beispiel #5
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));
            }
        }
Beispiel #6
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");
            }
        }
Beispiel #7
0
 // Define an extension method that can safely be called even on null objects
 // Calling ToString() on a null object causes an exception
 public static string SafeToString(this UTF8Buffer v)
 {
     return(v == null ? null : v.ToString());
 }