public override LambdaExpression TryGetConvertExpression(Type @from, Type to) { if (@from != to && @from.FullName == to.FullName && @from.Namespace == "Microsoft.SqlServer.Types") { var p = Expression.Parameter(@from); return(Expression.Lambda( Expression.Call(to, "Parse", new Type[0], Expression.New( MemberHelper.ConstructorOf(() => new SqlString("")), Expression.Call( Expression.Convert(p, typeof(object)), "ToString", new Type[0]))), p)); } return(base.TryGetConvertExpression(@from, to)); }
// TODO: move to SqlServerTypes.Configure? public override LambdaExpression?TryGetConvertExpression(Type @from, Type to) { if (@from != to && @from.FullName == to.FullName && @from.Namespace == SqlServerTypes.TypesNamespace) { var p = Expression.Parameter(@from); return(Expression.Lambda( Expression.Call(to, "Parse", Array <Type> .Empty, Expression.New( MemberHelper.ConstructorOf(() => new SqlString("")), Expression.Call( Expression.Convert(p, typeof(object)), "ToString", Array <Type> .Empty))), p)); } return(base.TryGetConvertExpression(@from, to)); }
protected override void OnConnectionTypeCreated(Type connectionType) { BitStringType = connectionType.Assembly.GetType("NpgsqlTypes.BitString", false); NpgsqlIntervalType = connectionType.Assembly.GetType("NpgsqlTypes.NpgsqlInterval", false); NpgsqlInetType = connectionType.Assembly.GetType("NpgsqlTypes.NpgsqlInet", true); NpgsqlTimeType = connectionType.Assembly.GetType("NpgsqlTypes.NpgsqlTime", false); NpgsqlTimeTZType = connectionType.Assembly.GetType("NpgsqlTypes.NpgsqlTimeTZ", false); NpgsqlPointType = connectionType.Assembly.GetType("NpgsqlTypes.NpgsqlPoint", true); NpgsqlLSegType = connectionType.Assembly.GetType("NpgsqlTypes.NpgsqlLSeg", true); NpgsqlBoxType = connectionType.Assembly.GetType("NpgsqlTypes.NpgsqlBox", true); NpgsqlPathType = connectionType.Assembly.GetType("NpgsqlTypes.NpgsqlPath", true); _npgsqlTimeStamp = connectionType.Assembly.GetType("NpgsqlTypes.NpgsqlTimeStamp", false); _npgsqlTimeStampTZ = connectionType.Assembly.GetType("NpgsqlTypes.NpgsqlTimeStampTZ", false); _npgsqlDate = connectionType.Assembly.GetType("NpgsqlTypes.NpgsqlDate", true); _npgsqlDateTime = connectionType.Assembly.GetType("NpgsqlTypes.NpgsqlDateTime", true); NpgsqlMacAddressType = connectionType.Assembly.GetType("NpgsqlTypes.NpgsqlMacAddress", false); NpgsqlCircleType = connectionType.Assembly.GetType("NpgsqlTypes.NpgsqlCircle", true); NpgsqlPolygonType = connectionType.Assembly.GetType("NpgsqlTypes.NpgsqlPolygon", true); if (BitStringType != null) { SetProviderField(BitStringType, BitStringType, "GetBitString"); } if (NpgsqlIntervalType != null) { SetProviderField(NpgsqlIntervalType, NpgsqlIntervalType, "GetInterval"); } if (NpgsqlTimeType != null) { SetProviderField(NpgsqlTimeType, NpgsqlTimeType, "GetTime"); } if (NpgsqlTimeTZType != null) { SetProviderField(NpgsqlTimeTZType, NpgsqlTimeTZType, "GetTimeTZ"); } if (_npgsqlTimeStamp != null) { SetProviderField(_npgsqlTimeStamp, _npgsqlTimeStamp, "GetTimeStamp"); } if (_npgsqlTimeStampTZ != null) { SetProviderField(_npgsqlTimeStampTZ, _npgsqlTimeStampTZ, "GetTimeStampTZ"); } if (NpgsqlMacAddressType != null) { SetProviderField(NpgsqlMacAddressType, NpgsqlMacAddressType, "GetProviderSpecificValue"); } if (_npgsqlDateTime != null) { SetProviderField(_npgsqlDateTime, _npgsqlDateTime, "GetTimeStamp"); } SetProviderField(NpgsqlInetType, NpgsqlInetType, "GetProviderSpecificValue"); SetProviderField(_npgsqlDate, _npgsqlDate, "GetDate"); if (_npgsqlTimeStampTZ != null) { // SetProviderField2<NpgsqlDataReader,DateTimeOffset,NpgsqlTimeStampTZ>((r,i) => (NpgsqlTimeStampTZ)r.GetProviderSpecificValue(i)); var dataReaderParameter = Expression.Parameter(DataReaderType, "r"); var indexParameter = Expression.Parameter(typeof(int), "i"); ReaderExpressions[new ReaderInfo { ToType = typeof(DateTimeOffset), ProviderFieldType = _npgsqlTimeStampTZ }] = Expression.Lambda( Expression.Convert( Expression.Call(dataReaderParameter, "GetProviderSpecificValue", null, indexParameter), _npgsqlTimeStampTZ), dataReaderParameter, indexParameter); } _setMoney = GetSetParameter(connectionType, "NpgsqlParameter", "NpgsqlDbType", "NpgsqlTypes.NpgsqlDbType", "Money"); _setVarBinary = GetSetParameter(connectionType, "NpgsqlParameter", "NpgsqlDbType", "NpgsqlTypes.NpgsqlDbType", "Bytea"); _setBoolean = GetSetParameter(connectionType, "NpgsqlParameter", "NpgsqlDbType", "NpgsqlTypes.NpgsqlDbType", "Boolean"); _setXml = GetSetParameter(connectionType, "NpgsqlParameter", "NpgsqlDbType", "NpgsqlTypes.NpgsqlDbType", "Xml"); _setText = GetSetParameter(connectionType, "NpgsqlParameter", "NpgsqlDbType", "NpgsqlTypes.NpgsqlDbType", "Text"); _setBit = GetSetParameter(connectionType, "NpgsqlParameter", "NpgsqlDbType", "NpgsqlTypes.NpgsqlDbType", "Bit"); _setHstore = GetSetParameter(connectionType, "NpgsqlParameter", "NpgsqlDbType", "NpgsqlTypes.NpgsqlDbType", "Hstore"); if (BitStringType != null) { MappingSchema.AddScalarType(BitStringType); } if (NpgsqlIntervalType != null) { MappingSchema.AddScalarType(NpgsqlIntervalType); } if (NpgsqlTimeType != null) { MappingSchema.AddScalarType(NpgsqlTimeType); } if (NpgsqlTimeTZType != null) { MappingSchema.AddScalarType(NpgsqlTimeTZType); } if (_npgsqlTimeStamp != null) { MappingSchema.AddScalarType(_npgsqlTimeStamp); } if (_npgsqlTimeStampTZ != null) { MappingSchema.AddScalarType(_npgsqlTimeStampTZ); } if (NpgsqlMacAddressType != null) { MappingSchema.AddScalarType(NpgsqlMacAddressType); } if (_npgsqlDateTime != null) { MappingSchema.AddScalarType(_npgsqlDateTime); } MappingSchema.AddScalarType(NpgsqlInetType); MappingSchema.AddScalarType(NpgsqlPointType); MappingSchema.AddScalarType(NpgsqlLSegType); MappingSchema.AddScalarType(NpgsqlBoxType); MappingSchema.AddScalarType(NpgsqlPathType); MappingSchema.AddScalarType(NpgsqlCircleType); MappingSchema.AddScalarType(_npgsqlDate); MappingSchema.AddScalarType(NpgsqlPolygonType); if (_npgsqlTimeStampTZ != null) { // SetConvertExpression<NpgsqlTimeStampTZ,DateTimeOffset>( // d => new DateTimeOffset(d.Year, d.Month, d.Day, d.Hours, d.Minutes, d.Seconds, d.Milliseconds, // new TimeSpan(d.TimeZone.Hours, d.TimeZone.Minutes, d.TimeZone.Seconds))); var p = Expression.Parameter(_npgsqlTimeStampTZ, "p"); MappingSchema.SetConvertExpression(_npgsqlTimeStampTZ, typeof(DateTimeOffset), Expression.Lambda( Expression.New( MemberHelper.ConstructorOf(() => new DateTimeOffset(0L, new TimeSpan())), Expression.PropertyOrField(p, "Ticks"), Expression.New( MemberHelper.ConstructorOf(() => new TimeSpan(0, 0, 0)), Expression.PropertyOrField(Expression.PropertyOrField(p, "TimeZone"), "Hours"), Expression.PropertyOrField(Expression.PropertyOrField(p, "TimeZone"), "Minutes"), Expression.PropertyOrField(Expression.PropertyOrField(p, "TimeZone"), "Seconds"))), p )); } if (_npgsqlDateTime != null) { var p = Expression.Parameter(_npgsqlDateTime, "p"); MappingSchema.SetConvertExpression(_npgsqlDateTime, typeof(DateTimeOffset), Expression.Lambda( Expression.New( MemberHelper.ConstructorOf(() => new DateTimeOffset(new DateTime())), Expression.PropertyOrField(p, "DateTime")), p)); } }
protected override void OnConnectionTypeCreated(Type connectionType) { var npgSql = connectionType.AssemblyEx(); // NpgsqlInterval was renamed to NpgsqlTimeSpan NpgsqlIntervalType = npgSql.GetType("NpgsqlTypes.NpgsqlInterval", false); NpgsqlIntervalType = NpgsqlIntervalType ?? npgSql.GetType("NpgsqlTypes.NpgsqlTimeSpan", false); BitStringType = npgSql.GetType("NpgsqlTypes.BitString", false); NpgsqlInetType = npgSql.GetType("NpgsqlTypes.NpgsqlInet", true); NpgsqlTimeType = npgSql.GetType("NpgsqlTypes.NpgsqlTime", false); NpgsqlTimeTZType = npgSql.GetType("NpgsqlTypes.NpgsqlTimeTZ", false); NpgsqlPointType = npgSql.GetType("NpgsqlTypes.NpgsqlPoint", true); NpgsqlLineType = npgSql.GetType("NpgsqlTypes.NpgsqlLine", false); NpgsqlLSegType = npgSql.GetType("NpgsqlTypes.NpgsqlLSeg", true); NpgsqlBoxType = npgSql.GetType("NpgsqlTypes.NpgsqlBox", true); NpgsqlPathType = npgSql.GetType("NpgsqlTypes.NpgsqlPath", true); _npgsqlTimeStamp = npgSql.GetType("NpgsqlTypes.NpgsqlTimeStamp", false); _npgsqlTimeStampTZ = npgSql.GetType("NpgsqlTypes.NpgsqlTimeStampTZ", false); NpgsqlDateType = npgSql.GetType("NpgsqlTypes.NpgsqlDate", true); NpgsqlDateTimeType = npgSql.GetType("NpgsqlTypes.NpgsqlDateTime", false); NpgsqlMacAddressType = npgSql.GetType("NpgsqlTypes.NpgsqlMacAddress", false); NpgsqlCircleType = npgSql.GetType("NpgsqlTypes.NpgsqlCircle", true); NpgsqlPolygonType = npgSql.GetType("NpgsqlTypes.NpgsqlPolygon", true); NpgsqlDbType = npgSql.GetType("NpgsqlTypes.NpgsqlDbType", true); // https://www.postgresql.org/docs/current/static/datatype.html // not all types are supported now // numeric types TryAddType("smallint", "Smallint"); TryAddType("integer", "Integer"); TryAddType("bigint", "Bigint"); TryAddType("numeric", "Numeric"); TryAddType("real", "Real"); TryAddType("double precision", "Double"); // monetary types TryAddType("money", "Money"); // character types TryAddType("character", "Char"); TryAddType("character varying", "Varchar"); TryAddType("text", "Text"); TryAddType("name", "Name"); TryAddType("char", "InternalChar"); // binary types TryAddType("bytea", "Bytea"); // date/time types (reltime missing from enum) TryAddType("timestamp", "Timestamp"); if (!TryAddType("timestamp with time zone", "TimestampTz")) { TryAddType("timestamp with time zone", "TimestampTZ"); } TryAddType("date", "Date"); TryAddType("time", "Time"); if (!TryAddType("time with time zone", "TimeTz")) { TryAddType("time with time zone", "TimeTZ"); } TryAddType("interval", "Interval"); TryAddType("abstime", "Abstime"); // boolean type TryAddType("boolean", "Boolean"); // geometric types TryAddType("point", "Point"); TryAddType("line", "Line"); TryAddType("lseg", "LSeg"); TryAddType("box", "Box"); TryAddType("path", "Path"); TryAddType("polygon", "Polygon"); TryAddType("circle", "Circle"); // network address types TryAddType("cidr", "Cidr"); TryAddType("inet", "Inet"); TryAddType("macaddr", "MacAddr"); HasMacAddr8 = TryAddType("macaddr8", "MacAddr8"); // bit string types TryAddType("bit", "Bit"); TryAddType("bit varying", "Varbit"); // text search types TryAddType("tsvector", "TsVector"); TryAddType("tsquery", "TsQuery"); // UUID type TryAddType("uuid", "Uuid"); // XML type TryAddType("xml", "Xml"); // JSON types TryAddType("json", "Json"); TryAddType("jsonb", "Jsonb"); // Object Identifier Types (only supported by npgsql) TryAddType("oid", "Oid"); TryAddType("regtype", "Regtype"); TryAddType("xid", "Xid"); TryAddType("cid", "Cid"); TryAddType("tid", "Tid"); // other types TryAddType("citext", "Citext"); TryAddType("hstore", "Hstore"); TryAddType("refcursor", "Refcursor"); TryAddType("oidvector", "Oidvector"); TryAddType("int2vector", "Int2Vector"); _npgsqlTypeArrayFlag = (int)Enum.Parse(NpgsqlDbType, "Array"); _npgsqlTypeRangeFlag = (int)Enum.Parse(NpgsqlDbType, "Range"); // https://github.com/linq2db/linq2db/pull/718 //if (npgSql.GetName().Version >= new Version(3, 1, 9)) //{ // _commandBehavior = CommandBehavior.KeyInfo; //} if (BitStringType != null) { SetProviderField(BitStringType, BitStringType, "GetBitString"); } if (NpgsqlIntervalType != null) { SetProviderField(NpgsqlIntervalType, NpgsqlIntervalType, "GetInterval"); } if (NpgsqlTimeType != null) { SetProviderField(NpgsqlTimeType, NpgsqlTimeType, "GetTime"); } if (NpgsqlTimeTZType != null) { SetProviderField(NpgsqlTimeTZType, NpgsqlTimeTZType, "GetTimeTZ"); } if (_npgsqlTimeStamp != null) { SetProviderField(_npgsqlTimeStamp, _npgsqlTimeStamp, "GetTimeStamp"); } if (_npgsqlTimeStampTZ != null) { SetProviderField(_npgsqlTimeStampTZ, _npgsqlTimeStampTZ, "GetTimeStampTZ"); } if (NpgsqlMacAddressType != null) { SetProviderField(NpgsqlMacAddressType, NpgsqlMacAddressType, "GetProviderSpecificValue"); } if (NpgsqlDateTimeType != null) { SetProviderField(NpgsqlDateTimeType, NpgsqlDateTimeType, "GetTimeStamp"); } SetProviderField(NpgsqlInetType, NpgsqlInetType, "GetProviderSpecificValue"); SetProviderField(NpgsqlDateType, NpgsqlDateType, "GetDate"); if (_npgsqlTimeStampTZ != null) { // SetProviderField2<NpgsqlDataReader,DateTimeOffset,NpgsqlTimeStampTZ>((r,i) => (NpgsqlTimeStampTZ)r.GetProviderSpecificValue(i)); var dataReaderParameter = Expression.Parameter(DataReaderType, "r"); var indexParameter = Expression.Parameter(typeof(int), "i"); ReaderExpressions[new ReaderInfo { ToType = typeof(DateTimeOffset), ProviderFieldType = _npgsqlTimeStampTZ }] = Expression.Lambda( Expression.Convert( Expression.Call(dataReaderParameter, "GetProviderSpecificValue", null, indexParameter), _npgsqlTimeStampTZ), dataReaderParameter, indexParameter); } _setMoney = GetSetParameter(connectionType, "NpgsqlParameter", "NpgsqlDbType", NpgsqlDbType, "Money"); _setVarBinary = GetSetParameter(connectionType, "NpgsqlParameter", "NpgsqlDbType", NpgsqlDbType, "Bytea"); _setBoolean = GetSetParameter(connectionType, "NpgsqlParameter", "NpgsqlDbType", NpgsqlDbType, "Boolean"); _setXml = GetSetParameter(connectionType, "NpgsqlParameter", "NpgsqlDbType", NpgsqlDbType, "Xml"); _setText = GetSetParameter(connectionType, "NpgsqlParameter", "NpgsqlDbType", NpgsqlDbType, "Text"); _setBit = GetSetParameter(connectionType, "NpgsqlParameter", "NpgsqlDbType", NpgsqlDbType, "Bit"); _setHstore = GetSetParameter(connectionType, "NpgsqlParameter", "NpgsqlDbType", NpgsqlDbType, "Hstore"); _setJson = GetSetParameter(connectionType, "NpgsqlParameter", "NpgsqlDbType", NpgsqlDbType, "Json"); _setJsonb = GetSetParameter(connectionType, "NpgsqlParameter", "NpgsqlDbType", NpgsqlDbType, "Jsonb"); if (BitStringType != null) { MappingSchema.AddScalarType(BitStringType); } if (NpgsqlTimeType != null) { MappingSchema.AddScalarType(NpgsqlTimeType); } if (NpgsqlTimeTZType != null) { MappingSchema.AddScalarType(NpgsqlTimeTZType); } if (_npgsqlTimeStamp != null) { MappingSchema.AddScalarType(_npgsqlTimeStamp); } if (_npgsqlTimeStampTZ != null) { MappingSchema.AddScalarType(_npgsqlTimeStampTZ); } if (NpgsqlMacAddressType != null) { MappingSchema.AddScalarType(NpgsqlMacAddressType); } AddUdtType(NpgsqlIntervalType); AddUdtType(NpgsqlDateType); AddUdtType(NpgsqlDateTimeType); AddUdtType(NpgsqlInetType); AddUdtType(typeof(IPAddress)); AddUdtType(typeof(PhysicalAddress)); AddUdtType(NpgsqlPointType); AddUdtType(NpgsqlLSegType); AddUdtType(NpgsqlBoxType); AddUdtType(NpgsqlPathType); AddUdtType(NpgsqlCircleType); AddUdtType(NpgsqlPolygonType); AddUdtType(NpgsqlLineType); if (_npgsqlTimeStampTZ != null) { // SetConvertExpression<NpgsqlTimeStampTZ,DateTimeOffset>( // d => new DateTimeOffset(d.Year, d.Month, d.Day, d.Hours, d.Minutes, d.Seconds, d.Milliseconds, // new TimeSpan(d.TimeZone.Hours, d.TimeZone.Minutes, d.TimeZone.Seconds))); var p = Expression.Parameter(_npgsqlTimeStampTZ, "p"); MappingSchema.SetConvertExpression(_npgsqlTimeStampTZ, typeof(DateTimeOffset), Expression.Lambda( Expression.New( MemberHelper.ConstructorOf(() => new DateTimeOffset(0L, new TimeSpan())), Expression.PropertyOrField(p, "Ticks"), Expression.New( MemberHelper.ConstructorOf(() => new TimeSpan(0, 0, 0)), Expression.PropertyOrField(Expression.PropertyOrField(p, "TimeZone"), "Hours"), Expression.PropertyOrField(Expression.PropertyOrField(p, "TimeZone"), "Minutes"), Expression.PropertyOrField(Expression.PropertyOrField(p, "TimeZone"), "Seconds"))), p )); } if (NpgsqlDateTimeType != null) { var p = Expression.Parameter(NpgsqlDateTimeType, "p"); var pi = p.Type.GetPropertyEx("DateTime"); Expression expr; if (pi != null) { expr = Expression.Property(p, pi); } else { expr = Expression.Call(p, "ToDateTime", null); } MappingSchema.SetConvertExpression(NpgsqlDateTimeType, typeof(DateTimeOffset), Expression.Lambda( Expression.New( MemberHelper.ConstructorOf(() => new DateTimeOffset(new DateTime())), expr), p)); } }
public static NpgsqlProviderAdapter GetInstance() { if (_instance == null) { lock (_syncRoot) if (_instance == null) { var assembly = Tools.TryLoadAssembly(AssemblyName, null); if (assembly == null) { throw new InvalidOperationException($"Cannot load assembly {AssemblyName}"); } var connectionType = assembly.GetType($"{ClientNamespace}.NpgsqlConnection", true) !; var parameterType = assembly.GetType($"{ClientNamespace}.NpgsqlParameter", true) !; var dataReaderType = assembly.GetType($"{ClientNamespace}.NpgsqlDataReader", true) !; var commandType = assembly.GetType($"{ClientNamespace}.NpgsqlCommand", true) !; var transactionType = assembly.GetType($"{ClientNamespace}.NpgsqlTransaction", true) !; var dbType = assembly.GetType($"{TypesNamespace}.NpgsqlDbType", true) !; var npgsqlDateType = assembly.GetType($"{TypesNamespace}.NpgsqlDate", true) !; var npgsqlPointType = assembly.GetType($"{TypesNamespace}.NpgsqlPoint", true) !; var npgsqlLSegType = assembly.GetType($"{TypesNamespace}.NpgsqlLSeg", true) !; var npgsqlBoxType = assembly.GetType($"{TypesNamespace}.NpgsqlBox", true) !; var npgsqlCircleType = assembly.GetType($"{TypesNamespace}.NpgsqlCircle", true) !; var npgsqlPathType = assembly.GetType($"{TypesNamespace}.NpgsqlPath", true) !; var npgsqlPolygonType = assembly.GetType($"{TypesNamespace}.NpgsqlPolygon", true) !; var npgsqlLineType = assembly.GetType($"{TypesNamespace}.NpgsqlLine", true) !; var npgsqlInetType = assembly.GetType($"{TypesNamespace}.NpgsqlInet", true) !; var npgsqlTimeSpanType = assembly.GetType($"{TypesNamespace}.NpgsqlTimeSpan", true) !; var npgsqlDateTimeType = assembly.GetType($"{TypesNamespace}.NpgsqlDateTime", true) !; var npgsqlRangeTType = assembly.GetType($"{TypesNamespace}.NpgsqlRange`1", true) !; var npgsqlBinaryImporterType = assembly.GetType($"{ClientNamespace}.NpgsqlBinaryImporter", true) !; var typeMapper = new TypeMapper(); typeMapper.RegisterTypeWrapper <NpgsqlConnection>(connectionType); typeMapper.RegisterTypeWrapper <NpgsqlParameter>(parameterType); typeMapper.RegisterTypeWrapper <NpgsqlDbType>(dbType); typeMapper.RegisterTypeWrapper <NpgsqlBinaryImporter>(npgsqlBinaryImporterType); typeMapper.FinalizeMappings(); var paramMapper = typeMapper.Type <NpgsqlParameter>(); var dbTypeBuilder = paramMapper.Member(p => p.NpgsqlDbType); var pConnection = Expression.Parameter(typeof(IDbConnection)); var pCommand = Expression.Parameter(typeof(string)); var beginBinaryImport = Expression.Lambda <Func <IDbConnection, string, NpgsqlBinaryImporter> >( typeMapper.MapExpression((IDbConnection conn, string command) => typeMapper.Wrap <NpgsqlBinaryImporter>(((NpgsqlConnection)conn).BeginBinaryImport(command)), pConnection, pCommand), pConnection, pCommand) .CompileExpression(); // create mapping schema var mappingSchema = new MappingSchema(); // date/time types AddUdtType(npgsqlDateType); AddUdtType(npgsqlDateTimeType); mappingSchema.SetDataType(npgsqlTimeSpanType, DataType.Interval); mappingSchema.SetDataType(npgsqlTimeSpanType.AsNullable(), DataType.Interval); // NpgsqlDateTimeType => DateTimeOffset { var p = Expression.Parameter(npgsqlDateTimeType, "p"); var pi = p.Type.GetProperty("DateTime"); Expression expr; if (pi != null) { // < 3.2.0 // https://github.com/npgsql/npgsql/commit/3894175f970b611f6428757a932b6393749da958#diff-c792076ac0455dd0f2852822ea38b0aaL166 expr = Expression.Property(p, pi); } else { // 3.2.0+ expr = Expression.Call(p, "ToDateTime", null); } var npgsqlDateTimeToDateTimeOffsetMapper = Expression.Lambda( Expression.New( MemberHelper.ConstructorOf(() => new DateTimeOffset(new DateTime())), expr), p); mappingSchema.SetConvertExpression(npgsqlDateTimeType, typeof(DateTimeOffset), npgsqlDateTimeToDateTimeOffsetMapper); } // inet types AddUdtType(npgsqlInetType); AddUdtType(typeof(IPAddress)); AddUdtType(typeof(PhysicalAddress)); // npgsql4 obsoletes NpgsqlInetType and returns ValueTuple<IPAddress, int> // still while it is here, we should be able to map it properly // (IPAddress, int) => NpgsqlInet { var valueTypeType = Type.GetType("System.ValueTuple`2", false); if (valueTypeType != null) { var inetTupleType = valueTypeType.MakeGenericType(typeof(IPAddress), typeof(int)); var p = Expression.Parameter(inetTupleType, "p"); var tupleToInetTypeMapper = Expression.Lambda( Expression.New( npgsqlInetType.GetConstructor(new[] { typeof(IPAddress), typeof(int) }) !, ExpressionHelper.Field(p, "Item1"), ExpressionHelper.Field(p, "Item2")), p); mappingSchema.SetConvertExpression(inetTupleType !, npgsqlInetType, tupleToInetTypeMapper); } } // ranges AddUdtType(npgsqlRangeTType); { void SetRangeConversion <T>(string?fromDbType = null, DataType fromDataType = DataType.Undefined, string?toDbType = null, DataType toDataType = DataType.Undefined) { var rangeType = npgsqlRangeTType.MakeGenericType(typeof(T)); var fromType = new DbDataType(rangeType, fromDataType, fromDbType); var toType = new DbDataType(typeof(DataParameter), toDataType, toDbType); var rangeParam = Expression.Parameter(rangeType, "p"); mappingSchema.SetConvertExpression(fromType, toType, Expression.Lambda( Expression.New( MemberHelper.ConstructorOf( () => new DataParameter("", null, DataType.Undefined, toDbType)), Expression.Constant(""), Expression.Convert(rangeParam, typeof(object)), Expression.Constant(toDataType), Expression.Constant(toDbType, typeof(string)) ) , rangeParam) ); } SetRangeConversion <byte>(); SetRangeConversion <int>(); SetRangeConversion <double>(); SetRangeConversion <float>(); SetRangeConversion <decimal>(); SetRangeConversion <DateTime>(fromDbType: "daterange", toDbType: "daterange"); SetRangeConversion <DateTime>(fromDbType: "tsrange", toDbType: "tsrange"); SetRangeConversion <DateTime>(toDbType: "tsrange"); SetRangeConversion <DateTime>(fromDbType: "tstzrange", toDbType: "tstzrange"); SetRangeConversion <DateTimeOffset>("tstzrange"); } // spatial types AddUdtType(npgsqlPointType); AddUdtType(npgsqlLSegType); AddUdtType(npgsqlBoxType); AddUdtType(npgsqlPathType); AddUdtType(npgsqlCircleType); AddUdtType(npgsqlPolygonType); AddUdtType(npgsqlLineType); _instance = new NpgsqlProviderAdapter( connectionType, dataReaderType, parameterType, commandType, transactionType, dbType, mappingSchema, npgsqlDateType, npgsqlPointType, npgsqlLSegType, npgsqlBoxType, npgsqlCircleType, npgsqlPathType, npgsqlPolygonType, npgsqlLineType, npgsqlInetType, npgsqlTimeSpanType, npgsqlDateTimeType, npgsqlRangeTType, typeMapper.BuildWrappedFactory((string connectionString) => new NpgsqlConnection(connectionString)), dbTypeBuilder.BuildSetter <IDbDataParameter>(), dbTypeBuilder.BuildGetter <IDbDataParameter>(), beginBinaryImport); void AddUdtType(Type type) { if (!type.IsValueType) { mappingSchema.AddScalarType(type, null, true, DataType.Udt); } else { mappingSchema.AddScalarType(type, DataType.Udt); mappingSchema.AddScalarType(type.AsNullable(), null, true, DataType.Udt); } } } } return(_instance); }
protected override void OnConnectionTypeCreated(Type connectionType) { var typesNamespace = OracleTools.AssemblyName + ".Types."; _oracleBFile = connectionType.AssemblyEx().GetType(typesNamespace + "OracleBFile", true); _oracleBinary = connectionType.AssemblyEx().GetType(typesNamespace + "OracleBinary", true); _oracleBlob = connectionType.AssemblyEx().GetType(typesNamespace + "OracleBlob", true); _oracleClob = connectionType.AssemblyEx().GetType(typesNamespace + "OracleClob", true); _oracleDate = connectionType.AssemblyEx().GetType(typesNamespace + "OracleDate", true); _oracleDecimal = connectionType.AssemblyEx().GetType(typesNamespace + "OracleDecimal", true); _oracleIntervalDS = connectionType.AssemblyEx().GetType(typesNamespace + "OracleIntervalDS", true); _oracleIntervalYM = connectionType.AssemblyEx().GetType(typesNamespace + "OracleIntervalYM", true); _oracleRefCursor = connectionType.AssemblyEx().GetType(typesNamespace + "OracleRefCursor", true); _oracleString = connectionType.AssemblyEx().GetType(typesNamespace + "OracleString", true); _oracleTimeStamp = connectionType.AssemblyEx().GetType(typesNamespace + "OracleTimeStamp", true); _oracleTimeStampLTZ = connectionType.AssemblyEx().GetType(typesNamespace + "OracleTimeStampLTZ", true); _oracleTimeStampTZ = connectionType.AssemblyEx().GetType(typesNamespace + "OracleTimeStampTZ", true); _oracleRef = connectionType.AssemblyEx().GetType(typesNamespace + "OracleRef", false); _oracleXmlType = connectionType.AssemblyEx().GetType(typesNamespace + "OracleXmlType", false); _oracleXmlStream = connectionType.AssemblyEx().GetType(typesNamespace + "OracleXmlStream", false); SetProviderField(_oracleBFile, _oracleBFile, "GetOracleBFile"); SetProviderField(_oracleBinary, _oracleBinary, "GetOracleBinary"); SetProviderField(_oracleBlob, _oracleBlob, "GetOracleBlob"); SetProviderField(_oracleClob, _oracleClob, "GetOracleClob"); SetProviderField(_oracleDate, _oracleDate, "GetOracleDate"); SetProviderField(_oracleDecimal, _oracleDecimal, "GetOracleDecimal"); SetProviderField(_oracleIntervalDS, _oracleIntervalDS, "GetOracleIntervalDS"); SetProviderField(_oracleIntervalYM, _oracleIntervalYM, "GetOracleIntervalYM"); SetProviderField(_oracleString, _oracleString, "GetOracleString"); SetProviderField(_oracleTimeStamp, _oracleTimeStamp, "GetOracleTimeStamp"); SetProviderField(_oracleTimeStampLTZ, _oracleTimeStampLTZ, "GetOracleTimeStampLTZ"); SetProviderField(_oracleTimeStampTZ, _oracleTimeStampTZ, "GetOracleTimeStampTZ"); try { if (_oracleRef != null) { SetProviderField(_oracleRef, _oracleRef, "GetOracleRef"); } } catch { } try { if (_oracleXmlType != null) { SetProviderField(_oracleXmlType, _oracleXmlType, "GetOracleXmlType"); } } catch { } var dataReaderParameter = Expression.Parameter(DataReaderType, "r"); var indexParameter = Expression.Parameter(typeof(int), "i"); { // static DateTimeOffset GetOracleTimeStampTZ(OracleDataReader rd, int idx) // { // var tstz = rd.GetOracleTimeStampTZ(idx); // return new DateTimeOffset( // tstz.Year, tstz.Month, tstz.Day, // tstz.Hour, tstz.Minute, tstz.Second, (int)tstz.Millisecond, // TimeSpan.Parse(tstz.TimeZone.TrimStart('+'))); // } var tstz = Expression.Parameter(_oracleTimeStampTZ, "tstz"); ReaderExpressions[new ReaderInfo { ToType = typeof(DateTimeOffset), ProviderFieldType = _oracleTimeStampTZ }] = Expression.Lambda( Expression.Block( new[] { tstz }, new Expression[] { Expression.Assign(tstz, Expression.Call(dataReaderParameter, "GetOracleTimeStampTZ", null, indexParameter)), Expression.New( MemberHelper.ConstructorOf(() => new DateTimeOffset(0, 0, 0, 0, 0, 0, 0, new TimeSpan())), Expression.PropertyOrField(tstz, "Year"), Expression.PropertyOrField(tstz, "Month"), Expression.PropertyOrField(tstz, "Day"), Expression.PropertyOrField(tstz, "Hour"), Expression.PropertyOrField(tstz, "Minute"), Expression.PropertyOrField(tstz, "Second"), Expression.Convert(Expression.PropertyOrField(tstz, "Millisecond"), typeof(int)), Expression.Call( MemberHelper.MethodOf(() => TimeSpan.Parse("")), Expression.Call( Expression.PropertyOrField(tstz, "TimeZone"), MemberHelper.MethodOf(() => "".TrimStart(' ')), Expression.NewArrayInit(typeof(char), Expression.Constant('+')))) ) }), dataReaderParameter, indexParameter); } { // static DateTimeOffset GetOracleTimeStampLTZ(OracleDataReader rd, int idx) // { // var tstz = rd.GetOracleTimeStampLTZ(idx).ToOracleTimeStampTZ(); // return new DateTimeOffset( // tstz.Year, tstz.Month, tstz.Day, // tstz.Hour, tstz.Minute, tstz.Second, (int)tstz.Millisecond, // TimeSpan.Parse(tstz.TimeZone.TrimStart('+'))); // } var tstz = Expression.Parameter(_oracleTimeStampTZ, "tstz"); ReaderExpressions[new ReaderInfo { ToType = typeof(DateTimeOffset), ProviderFieldType = _oracleTimeStampLTZ }] = Expression.Lambda( Expression.Block( new[] { tstz }, new Expression[] { Expression.Assign( tstz, Expression.Call( Expression.Call(dataReaderParameter, "GetOracleTimeStampLTZ", null, indexParameter), "ToOracleTimeStampTZ", null, null)), Expression.New( MemberHelper.ConstructorOf(() => new DateTimeOffset(0, 0, 0, 0, 0, 0, 0, new TimeSpan())), Expression.PropertyOrField(tstz, "Year"), Expression.PropertyOrField(tstz, "Month"), Expression.PropertyOrField(tstz, "Day"), Expression.PropertyOrField(tstz, "Hour"), Expression.PropertyOrField(tstz, "Minute"), Expression.PropertyOrField(tstz, "Second"), Expression.Convert(Expression.PropertyOrField(tstz, "Millisecond"), typeof(int)), Expression.Call( MemberHelper.MethodOf(() => TimeSpan.Parse("")), Expression.Call( Expression.PropertyOrField(tstz, "TimeZone"), MemberHelper.MethodOf(() => "".TrimStart(' ')), Expression.NewArrayInit(typeof(char), Expression.Constant('+')))) ) }), dataReaderParameter, indexParameter); } { // value = new OracleTimeStampTZ(dto.Year, dto.Month, dto.Day, dto.Hour, dto.Minute, dto.Second, dto.Millisecond, zone); var dto = Expression.Parameter(typeof(DateTimeOffset), "dto"); var zone = Expression.Parameter(typeof(string), "zone"); _createOracleTimeStampTZ = Expression.Lambda <Func <DateTimeOffset, string, object> >( Expression.Convert( Expression.New( _oracleTimeStampTZ.GetConstructorEx(new[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(string) }), Expression.PropertyOrField(dto, "Year"), Expression.PropertyOrField(dto, "Month"), Expression.PropertyOrField(dto, "Day"), Expression.PropertyOrField(dto, "Hour"), Expression.PropertyOrField(dto, "Minute"), Expression.PropertyOrField(dto, "Second"), Expression.PropertyOrField(dto, "Millisecond"), zone), typeof(object)), dto, zone ).Compile(); } _setSingle = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "BinaryFloat"); _setDouble = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "BinaryDouble"); _setText = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "Clob"); _setNText = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "NClob"); _setImage = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "Blob"); _setBinary = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "Blob"); _setVarBinary = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "Blob"); _setDate = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "Date"); _setSmallDateTime = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "Date"); _setDateTime2 = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "TimeStamp"); _setDateTimeOffset = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "TimeStampTZ"); _setGuid = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "Raw"); MappingSchema.AddScalarType(_oracleBFile, GetNullValue(_oracleBFile), true, DataType.VarChar); // ? MappingSchema.AddScalarType(_oracleBinary, GetNullValue(_oracleBinary), true, DataType.VarBinary); MappingSchema.AddScalarType(_oracleBlob, GetNullValue(_oracleBlob), true, DataType.Blob); // ? MappingSchema.AddScalarType(_oracleClob, GetNullValue(_oracleClob), true, DataType.NText); MappingSchema.AddScalarType(_oracleDate, GetNullValue(_oracleDate), true, DataType.DateTime); MappingSchema.AddScalarType(_oracleDecimal, GetNullValue(_oracleDecimal), true, DataType.Decimal); MappingSchema.AddScalarType(_oracleIntervalDS, GetNullValue(_oracleIntervalDS), true, DataType.Time); // ? MappingSchema.AddScalarType(_oracleIntervalYM, GetNullValue(_oracleIntervalYM), true, DataType.Date); // ? MappingSchema.AddScalarType(_oracleRefCursor, GetNullValue(_oracleRefCursor), true, DataType.Binary); // ? MappingSchema.AddScalarType(_oracleString, GetNullValue(_oracleString), true, DataType.NVarChar); MappingSchema.AddScalarType(_oracleTimeStamp, GetNullValue(_oracleTimeStamp), true, DataType.DateTime2); MappingSchema.AddScalarType(_oracleTimeStampLTZ, GetNullValue(_oracleTimeStampLTZ), true, DataType.DateTimeOffset); MappingSchema.AddScalarType(_oracleTimeStampTZ, GetNullValue(_oracleTimeStampTZ), true, DataType.DateTimeOffset); if (_oracleRef != null) { MappingSchema.AddScalarType(_oracleRef, GetNullValue(_oracleRef), true, DataType.Binary); // ? } if (_oracleXmlType != null) { MappingSchema.AddScalarType(_oracleXmlType, GetNullValue(_oracleXmlType), true, DataType.Xml); } if (_oracleXmlStream != null) { MappingSchema.AddScalarType(_oracleXmlStream, GetNullValue(_oracleXmlStream), true, DataType.Xml); // ? } }