/// <summary> /// Convert to a postgresql timestamp. /// </summary> internal static byte[] ToDateTime(NpgsqlNativeTypeInfo TypeInfo, Object NativeData, Boolean forExtendedQuery, NativeToBackendTypeConverterOptions options, bool arrayElement) { if (!(NativeData is DateTime)) { return(ExtendedNativeToBackendTypeConverter.ToTimeStamp(TypeInfo, NativeData, forExtendedQuery, options, arrayElement)); } if (DateTime.MaxValue.Equals(NativeData)) { return(ASCIIByteArrays.INFINITY); } if (DateTime.MinValue.Equals(NativeData)) { return(ASCIIByteArrays.NEG_INFINITY); } return(BackendEncoding.UTF8Encoding.GetBytes((((DateTime)NativeData).ToString("yyyy-MM-dd HH:mm:ss.ffffff", DateTimeFormatInfo.InvariantInfo)))); }
internal static byte[] ToTimeTZ(NpgsqlNativeTypeInfo typeInfo, object nativeData, Boolean forExtendedQuery, NativeToBackendTypeConverterOptions options, bool arrayElement) { if (nativeData is DateTime) { return(BasicNativeToBackendTypeConverter.ToTime(typeInfo, nativeData, forExtendedQuery, options, arrayElement)); } NpgsqlTimeTZ time; if (nativeData is TimeSpan) { time = (NpgsqlTimeTZ)(TimeSpan)nativeData; } else { time = (NpgsqlTimeTZ)nativeData; } return(BackendEncoding.UTF8Encoding.GetBytes(time.ToString())); }
/// <summary> /// Append all array data to the binary stream. /// </summary> private void WriteBinaryArrayData(NpgsqlNativeTypeInfo TypeInfo, Array nativeData, NativeToBackendTypeConverterOptions options, MemoryStream dst, int dimensionOffset, int[] dimensionOffsets) { int dimensionLength = nativeData.GetLength(dimensionOffset); int dimensionLBound = nativeData.GetLowerBound(dimensionOffset); if (dimensionOffset < nativeData.Rank - 1) { // Drill down recursively until we hit a single dimension array. for (int i = dimensionLBound; i < dimensionLBound + dimensionLength; i++) { dimensionOffsets[dimensionOffset] = i; WriteBinaryArrayData(TypeInfo, nativeData, options, dst, dimensionOffset + 1, dimensionOffsets); } } else { // Write the individual array elements to the output stream. for (int i = dimensionLBound; i < dimensionLBound + dimensionLength; i++) { object elementNative; dimensionOffsets[dimensionOffset] = i; elementNative = nativeData.GetValue(dimensionOffsets); if (elementNative == null || elementNative == DBNull.Value) { // Write length identifier -1 indicating NULL value. PGUtil.WriteInt32(dst, -1); } else { byte[] elementBinary; elementBinary = (byte[])_elementConverter.ConvertToBackend(elementNative, true, options); // Write lenght identifier. PGUtil.WriteInt32(dst, elementBinary.Length); // Write element data. dst.Write(elementBinary, 0, elementBinary.Length); } } } }
/// <summary> /// Add the given NpgsqlNativeTypeInfo to this mapping. /// </summary> public void AddType(NpgsqlNativeTypeInfo T) { if (NameIndex.ContainsKey(T.Name)) { throw new Exception("Type already mapped"); } NameIndex[T.Name] = T; NpgsqlDbTypeIndex[T.NpgsqlDbType] = T; DbTypeIndex[T.DbType] = T; if (!T.IsArray) { NpgsqlNativeTypeInfo arrayType = NpgsqlNativeTypeInfo.ArrayOf(T); NameIndex[arrayType.Name] = arrayType; NameIndex[arrayType.CastName] = arrayType; NpgsqlDbTypeIndex[arrayType.NpgsqlDbType] = arrayType; } }
/// <summary> /// Open path. /// </summary> internal static byte[] ToPath(NpgsqlNativeTypeInfo TypeInfo, Object NativeData, Boolean forExtendedQuery, NativeToBackendTypeConverterOptions options, bool arrayElement) { StringBuilder B = null; try { B = new StringBuilder(); foreach (NpgsqlPoint P in ((NpgsqlPath)NativeData)) { B.AppendFormat(CultureInfo.InvariantCulture, "{0}({1},{2})", (B.Length > 0 ? "," : ""), P.X, P.Y); } return(BackendEncoding.UTF8Encoding.GetBytes(String.Format("[{0}]", B))); } finally { B = null; } }
/// <summary> /// Find a NpgsqlNativeTypeInfo in the default types map that can handle objects /// of the given System.Type. /// </summary> public static bool TryGetNativeTypeInfo(Type type, out NpgsqlNativeTypeInfo typeInfo) { if (NativeTypeMapping.TryGetValue(type, out typeInfo)) { return(true); } // At this point there is no direct mapping, so we see if we have an array or IEnumerable<T>. // Note that we checked for a direct mapping first, so if there is a direct mapping of a class // which implements IEnumerable<T> we will use that (currently this is only string, which // implements IEnumerable<char>. Type elementType = null; NpgsqlNativeTypeInfo elementTypeInfo = null; if (TestTypedEnumerator(type, out elementType) && TryGetNativeTypeInfo(elementType, out elementTypeInfo)) { typeInfo = NpgsqlNativeTypeInfo.ArrayOf(elementTypeInfo); return(true); } return(false); }
/// <summary> /// Box. /// </summary> internal static byte[] ToBox(NpgsqlNativeTypeInfo TypeInfo, Object NativeData, Boolean forExtendedQuery, NativeToBackendTypeConverterOptions options, bool arrayElement) { /*if (NativeData.GetType() == typeof(Rectangle)) { * Rectangle R = (Rectangle)NativeData; * return String.Format(CultureInfo.InvariantCulture, "({0},{1}),({2},{3})", R.Left, R.Top, R.Left + R.Width, R.Top + R.Height); * } else if (NativeData.GetType() == typeof(RectangleF)) { * RectangleF R = (RectangleF)NativeData; * return String.Format(CultureInfo.InvariantCulture, "({0},{1}),({2},{3})", R.Left, R.Top, R.Left + R.Width, R.Top + R.Height);*/ if (NativeData is NpgsqlBox) { NpgsqlBox box = (NpgsqlBox)NativeData; return (BackendEncoding.UTF8Encoding.GetBytes(String.Format(CultureInfo.InvariantCulture, "({0},{1}),({2},{3})", box.LowerLeft.X, box.LowerLeft.Y, box.UpperRight.X, box.UpperRight.Y))); } else { throw new InvalidCastException("Unable to cast data to Rectangle type"); } }
private bool WriteItemText(NpgsqlNativeTypeInfo TypeInfo, object item, MemoryStream array, Boolean forExtendedQuery, NativeToBackendTypeConverterOptions options) { //item could be: //an Ienumerable - in which case we call WriteEnumeration //an element - in which case we call the NpgsqlNativeTypeInfo for that type to serialise it. //an array - in which case we call WriteArray, // Even an string being an IEnumerable, it shouldn't be processed. It will be processed on the last else. // See http://pgfoundry.org/tracker/?func=detail&atid=592&aid=1010514&group_id=1000140 for more info. if (item == null || NpgsqlTypesHelper.DefinedType(item)) { byte[] element; element = _elementConverter.ConvertToBackend(item, forExtendedQuery, options, true); array.Write(element, 0, element.Length); return(true); } else if (item is Array) { return(WriteArrayText(TypeInfo, item as Array, array, forExtendedQuery, options)); } else if (item is IEnumerable) { return(WriteEnumeration(TypeInfo, item as IEnumerable, array, forExtendedQuery, options)); } else {//This shouldn't really be reachable. byte[] element; element = _elementConverter.ConvertToBackend(item, forExtendedQuery, options, true); array.Write(element, 0, element.Length); return(true); } }
internal static byte[] DoubleToFloat8Text(NpgsqlNativeTypeInfo TypeInfo, Object NativeData, Boolean forExtendedQuery, NativeToBackendTypeConverterOptions options, bool arrayElement) { //Formats accepted vary according to locale, but it always accepts a plain number (no currency or //grouping symbols) passed as a string (with the appropriate cast appended, as UseCast will cause //to happen. if (!arrayElement) { var asDouble = (double)NativeData; if (double.IsNaN(asDouble)) { return(ASCIIByteArrays.NAN_QUOTED); } if (double.IsPositiveInfinity(asDouble)) { return(ASCIIByteArrays.INFINITY_QUOTED); } if (double.IsNegativeInfinity(asDouble)) { return(ASCIIByteArrays.NEG_INFINITY_QUOTED); } } return(BackendEncoding.UTF8Encoding.GetBytes(((IFormattable)NativeData).ToString("R", CultureInfo.InvariantCulture.NumberFormat))); }
/// <summary> /// Binary data, escaped and quoted as required. /// </summary> internal static byte[] ByteArrayToByteaText(NpgsqlNativeTypeInfo TypeInfo, Object NativeData, bool forExtendedQuery, NativeToBackendTypeConverterOptions options, bool arrayElement) { StringEncodingInfo encodingInfo; // Using a four bit hash key derived from the options at hand, // find the correct string encoding info object. encodingInfo = stringEncodingInfoTable[ StringEncodingInfoHash( forExtendedQuery, options.UseConformantStrings, options.Supports_E_StringPrefix, arrayElement ) ]; if (!options.SupportsHexByteFormat) { return(ByteArrayToByteaTextEscaped((byte[])NativeData, encodingInfo)); } else { return(ByteArrayToByteaTextHexFormat((byte[])NativeData, encodingInfo)); } }
/// <summary> /// Retrieve the NpgsqlNativeTypeInfo with the given DbType. /// </summary> public bool TryGetValue(DbType dbType, out NpgsqlNativeTypeInfo typeInfo) { return(DbTypeIndex.TryGetValue(dbType, out typeInfo)); }
/// <summary> /// LSeg. /// </summary> internal static byte[] ToLSeg(NpgsqlNativeTypeInfo TypeInfo, Object NativeData, Boolean forExtendedQuery, NativeToBackendTypeConverterOptions options, bool arrayElement) { NpgsqlLSeg S = (NpgsqlLSeg)NativeData; return(BackendEncoding.UTF8Encoding.GetBytes(String.Format(CultureInfo.InvariantCulture, "{0},{1},{2},{3}", S.Start.X, S.Start.Y, S.End.X, S.End.Y))); }
/// <summary> /// Convert a System.Double to a postgres float8. /// </summary> internal static byte[] DoubleToFloat8Binary(NpgsqlNativeTypeInfo TypeInfo, Object NativeData, NativeToBackendTypeConverterOptions options) { return(PGUtil.HostNetworkByteOrderSwap(BitConverter.GetBytes(Convert.ToDouble(NativeData)))); }
internal static byte[] ToBasicType <T>(NpgsqlNativeTypeInfo TypeInfo, object NativeData, Boolean forExtendedQuery, NativeToBackendTypeConverterOptions options, bool arrayElement) { // This double cast is needed in order to get the enum type handled correctly (IConvertible) // and the decimal separator always as "." regardless of culture (IFormattable) return(BackendEncoding.UTF8Encoding.GetBytes((((IFormattable)((IConvertible)NativeData).ToType(typeof(T), null)).ToString(null, CultureInfo.InvariantCulture.NumberFormat)))); }
/// <summary> /// Find a NpgsqlNativeTypeInfo in the default types map that can handle objects /// of the given DbType. /// </summary> public static bool TryGetNativeTypeInfo(DbType dbType, out NpgsqlNativeTypeInfo typeInfo) { return(NativeTypeMapping.TryGetValue(dbType, out typeInfo)); }
/// <summary> /// Circle. /// </summary> internal static byte[] ToCircle(NpgsqlNativeTypeInfo TypeInfo, Object NativeData, Boolean forExtendedQuery, NativeToBackendTypeConverterOptions options, bool arrayElement) { NpgsqlCircle C = (NpgsqlCircle)NativeData; return(BackendEncoding.UTF8Encoding.GetBytes(String.Format(CultureInfo.InvariantCulture, "{0},{1},{2}", C.Center.X, C.Center.Y, C.Radius))); }
/// <summary> /// Convert to a postgresql boolean text format. /// </summary> internal static byte[] BooleanToBooleanText(NpgsqlNativeTypeInfo TypeInfo, Object NativeData, Boolean forExtendedQuery, NativeToBackendTypeConverterOptions options, bool arrayElement) { return(((bool)NativeData) ? ASCIIByteArrays.TRUE : ASCIIByteArrays.FALSE); }
/// <summary> /// Binary data, raw. /// </summary> internal static byte[] ByteArrayToByteaBinary(NpgsqlNativeTypeInfo TypeInfo, Object NativeData, NativeToBackendTypeConverterOptions options) { return((byte[])NativeData); }
/// <summary> /// Convert a string to UTF8 encoded text. /// </summary> internal static byte[] StringToTextBinary(NpgsqlNativeTypeInfo TypeInfo, Object NativeData, NativeToBackendTypeConverterOptions options) { return(BackendEncoding.UTF8Encoding.GetBytes(NativeData.ToString())); }
public static NpgsqlNativeTypeInfo GetNativeTypeInfo(Type Type) { NpgsqlNativeTypeInfo ret = null; return(TryGetNativeTypeInfo(Type, out ret) ? ret : null); }
/// <summary> /// Convert to a postgresql boolean binary format. /// </summary> internal static byte[] BooleanToBooleanBinary(NpgsqlNativeTypeInfo TypeInfo, Object NativeData, NativeToBackendTypeConverterOptions options) { return(((bool)NativeData) ? ASCIIByteArrays.Byte_1 : ASCIIByteArrays.Byte_0); }
/// <summary> /// Create an ArrayNativeToBackendTypeConverter with the element converter passed /// </summary> /// <param name="elementConverter">The <see cref="NpgsqlNativeTypeInfo"/> that would be used to serialise the element type.</param> public ArrayNativeToBackendTypeConverter(NpgsqlNativeTypeInfo elementConverter) { _elementConverter = elementConverter; }
public bool TryGetValue(string name, out NpgsqlNativeTypeInfo typeInfo) { return(NameIndex.TryGetValue(name, out typeInfo)); }
/// <summary> /// Convert to a postgresql binary int8. /// </summary> internal static byte[] Int64ToInt8Binary(NpgsqlNativeTypeInfo TypeInfo, Object NativeData, NativeToBackendTypeConverterOptions options) { return(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Convert.ToInt64(NativeData)))); }
/// <summary> /// Retrieve the NpgsqlNativeTypeInfo with the given Type. /// </summary> public bool TryGetValue(Type type, out NpgsqlNativeTypeInfo typeInfo) { return(TypeIndex.TryGetValue(type, out typeInfo)); }
private bool WriteArrayText(NpgsqlNativeTypeInfo TypeInfo, Array ar, MemoryStream array, Boolean forExtendedQuery, NativeToBackendTypeConverterOptions options) { bool writtenSomething = false; //we need to know the size of each dimension. int c = ar.Rank; List <int> lengths = new List <int>(c); bool firstItem = true; do { lengths.Add(ar.GetLength(--c)); }while (c != 0); //c is now zero. Might as well reuse it! foreach (object item in ar) { if (firstItem) { firstItem = false; } else { array.WriteByte((byte)ASCIIBytes.Comma); } //to work out how many [ characters we need we need to work where we are compared to the dimensions. //Say we are at position 24 in a 3 * 4 * 5 array. //We're at the end of a row as 24 % 3 == 0 so write one [ for that. //We're at the end of a square as 24 % (3 * 4) == 24 % (12) == 0 so write one [ for that. //We're not at the end of a cube as 24 % (3 * 4 * 5) == 24 % (30) != 0, so we're finished for that pass. int curlength = 1; foreach (int lengthTest in lengths) { if (c % (curlength *= lengthTest) == 0) { array.WriteByte((byte)ASCIIBytes.BraceCurlyLeft); } else { break; } } //Write whatever the element is. writtenSomething |= WriteItemText(TypeInfo, item, array, forExtendedQuery, options); ++c; //up our counter for knowing when to write [ and ] //same logic as above for writing [ this time writing ] curlength = 1; foreach (int lengthTest in lengths) { if (c % (curlength *= lengthTest) == 0) { array.WriteByte((byte)ASCIIBytes.BraceCurlyRight); } else { break; } } } return(writtenSomething); }