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)); } }
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)); } }
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"); } }