Esempio n. 1
0
 public static bool AddScalarTypes_iDB2(this MappingSchema mappingSchema)
 {
     mappingSchema.AddScalarType(typeof(iDB2BigInt), iDB2BigInt.Null, canBeNull: true, DataType.Int64);
     mappingSchema.AddScalarType(typeof(iDB2Char), iDB2Char.Null, canBeNull: true, DataType.Char);
     mappingSchema.AddScalarType(typeof(iDB2Date), iDB2Date.Null, canBeNull: true, DataType.Date);
     mappingSchema.AddScalarType(typeof(iDB2Decimal), iDB2Decimal.Null, canBeNull: true, DataType.Decimal);
     mappingSchema.AddScalarType(typeof(iDB2Double), iDB2Double.Null, canBeNull: true, DataType.Double);
     mappingSchema.AddScalarType(typeof(iDB2Integer), iDB2Integer.Null, canBeNull: true, DataType.Int32);
     mappingSchema.AddScalarType(typeof(iDB2SmallInt), iDB2SmallInt.Null, canBeNull: true, DataType.Int16);
     mappingSchema.AddScalarType(typeof(iDB2Time), iDB2Time.Null, canBeNull: true, DataType.Time);
     mappingSchema.AddScalarType(typeof(iDB2TimeStamp), iDB2TimeStamp.Null, canBeNull: true, DataType.DateTime2);
     mappingSchema.AddScalarType(typeof(iDB2VarChar), iDB2VarChar.Null, canBeNull: true, DataType.VarChar);
     return(true);
 }
Esempio n. 2
0
        protected override void OnConnectionTypeCreated(Type connectionType)
        {
            _ifxBlob     = connectionType.AssemblyEx().GetType("IBM.Data.Informix.IfxBlob", true);
            _ifxClob     = connectionType.AssemblyEx().GetType("IBM.Data.Informix.IfxClob", true);
            _ifxDecimal  = connectionType.AssemblyEx().GetType("IBM.Data.Informix.IfxDecimal", true);
            _ifxDateTime = connectionType.AssemblyEx().GetType("IBM.Data.Informix.IfxDateTime", true);
            _ifxTimeSpan = connectionType.AssemblyEx().GetType("IBM.Data.Informix.IfxTimeSpan", true);

            if (!Configuration.AvoidSpecificDataProviderAPI)
            {
                SetField(typeof(Int64), "BIGINT", "GetBigInt");

                SetProviderField(_ifxDecimal, typeof(decimal), "GetIfxDecimal");
                SetProviderField(_ifxDateTime, typeof(DateTime), "GetIfxDateTime");
                SetProviderField(_ifxTimeSpan, typeof(TimeSpan), "GetIfxTimeSpan");
            }

            var p = Expression.Parameter(typeof(TimeSpan));

            _newIfxTimeSpan = Expression.Lambda <Func <TimeSpan, object> >(
                Expression.Convert(
                    Expression.New(_ifxTimeSpan.GetConstructorEx(new[] { typeof(TimeSpan) }), p),
                    typeof(object)),
                p).Compile();

            _setText = GetSetParameter(connectionType, "IfxParameter", "IfxType", "IfxType", "Clob");

            MappingSchema.AddScalarType(_ifxBlob, GetNullValue(_ifxBlob), true, DataType.VarBinary);
            MappingSchema.AddScalarType(_ifxClob, GetNullValue(_ifxClob), true, DataType.Text);
            MappingSchema.AddScalarType(_ifxDateTime, GetNullValue(_ifxDateTime), true, DataType.DateTime2);
            MappingSchema.AddScalarType(_ifxDecimal, GetNullValue(_ifxDecimal), true, DataType.Decimal);
            MappingSchema.AddScalarType(_ifxTimeSpan, GetNullValue(_ifxTimeSpan), true, DataType.Time);
            //AddScalarType(typeof(IfxMonthSpan),   IfxMonthSpan.  Null, DataType.Time);
        }
        public void AddUdtType(Type type, string udtName, object?defaultValue, DataType dataType = DataType.Undefined)
        {
            MappingSchema.AddScalarType(type, defaultValue, dataType);

            _udtTypeNames[type] = udtName;
            _udtTypes[udtName]  = type;
        }
        public void AddUdtType <T>(string udtName, T defaultValue, DataType dataType = DataType.Undefined)
        {
            MappingSchema.AddScalarType(typeof(T), defaultValue, dataType);

            _udtTypeNames[typeof(T)] = udtName;
            _udtTypes[udtName]       = typeof(T);
        }
Esempio n. 5
0
 internal static void Configure(MappingSchema mappingSchema)
 {
     foreach (var type in _types.Value)
     {
         mappingSchema.AddScalarType(type.Type, type.Null, true, DataType.Udt);
     }
 }
Esempio n. 6
0
        protected override void OnConnectionTypeCreated(Type connectionType)
        {
            _db2Int64        = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2Int64", true);
            _db2Int32        = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2Int32", true);
            _db2Int16        = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2Int16", true);
            _db2Decimal      = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2Decimal", true);
            _db2DecimalFloat = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2DecimalFloat", true);
            _db2Real         = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2Real", true);
            _db2Real370      = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2Real370", true);
            _db2Double       = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2Double", true);
            _db2String       = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2String", true);
            _db2Clob         = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2Clob", true);
            _db2Binary       = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2Binary", true);
            _db2Blob         = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2Blob", true);
            _db2Date         = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2Date", true);
            _db2Time         = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2Time", true);
            _db2TimeStamp    = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2TimeStamp", true);
            _db2Xml          = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2Xml", true);
            _db2RowId        = connectionType.Assembly.GetType("IBM.Data.DB2Types.DB2RowId", true);


            SetProviderField(_db2Int64, typeof(Int64), "GetDB2Int64");
            SetProviderField(_db2Int32, typeof(Int32), "GetDB2Int32");
            SetProviderField(_db2Int16, typeof(Int16), "GetDB2Int16");
            SetProviderField(_db2Decimal, typeof(Decimal), "GetDB2Decimal");
            SetProviderField(_db2DecimalFloat, typeof(Decimal), "GetDB2DecimalFloat");
            SetProviderField(_db2Real, typeof(Single), "GetDB2Real");
            SetProviderField(_db2Real370, typeof(Single), "GetDB2Real370");
            SetProviderField(_db2Double, typeof(Double), "GetDB2Double");
            SetProviderField(_db2String, typeof(String), "GetDB2String");
            SetProviderField(_db2Clob, typeof(String), "GetDB2Clob");
            SetProviderField(_db2Binary, typeof(byte[]), "GetDB2Binary");
            SetProviderField(_db2Blob, typeof(byte[]), "GetDB2Blob");
            SetProviderField(_db2Date, typeof(DateTime), "GetDB2Date");
            SetProviderField(_db2Time, typeof(TimeSpan), "GetDB2Time");
            SetProviderField(_db2TimeStamp, typeof(DateTime), "GetDB2TimeStamp");
            SetProviderField(_db2Xml, typeof(string), "GetDB2Xml");
            SetProviderField(_db2RowId, typeof(byte[]), "GetDB2RowId");

            MappingSchema.AddScalarType(_db2Int64, GetNullValue(_db2Int64), true, DataType.Int64);
            MappingSchema.AddScalarType(_db2Int32, GetNullValue(_db2Int32), true, DataType.Int32);
            MappingSchema.AddScalarType(_db2Int16, GetNullValue(_db2Int16), true, DataType.Int16);
            MappingSchema.AddScalarType(_db2Decimal, GetNullValue(_db2Decimal), true, DataType.Decimal);
            MappingSchema.AddScalarType(_db2DecimalFloat, GetNullValue(_db2DecimalFloat), true, DataType.Decimal);
            MappingSchema.AddScalarType(_db2Real, GetNullValue(_db2Real), true, DataType.Single);
            MappingSchema.AddScalarType(_db2Real370, GetNullValue(_db2Real370), true, DataType.Single);
            MappingSchema.AddScalarType(_db2Double, GetNullValue(_db2Double), true, DataType.Double);
            MappingSchema.AddScalarType(_db2String, GetNullValue(_db2String), true, DataType.NVarChar);
            MappingSchema.AddScalarType(_db2Clob, GetNullValue(_db2Clob), true, DataType.NText);
            MappingSchema.AddScalarType(_db2Binary, GetNullValue(_db2Binary), true, DataType.VarBinary);
            MappingSchema.AddScalarType(_db2Blob, GetNullValue(_db2Blob), true, DataType.Blob);
            MappingSchema.AddScalarType(_db2Date, GetNullValue(_db2Date), true, DataType.Date);
            MappingSchema.AddScalarType(_db2Time, GetNullValue(_db2Time), true, DataType.Time);
            MappingSchema.AddScalarType(_db2TimeStamp, GetNullValue(_db2TimeStamp), true, DataType.DateTime2);
            MappingSchema.AddScalarType(_db2Xml, GetNullValue(_db2Xml), true, DataType.Xml);
            MappingSchema.AddScalarType(_db2RowId, GetNullValue(_db2RowId), true, DataType.VarBinary);

            _setBlob = GetSetParameter(connectionType, "DB2Parameter", "DB2Type", "DB2Type", "Blob");
        }
        private void SetupCustomTypes(MappingSchema ms, bool asDataParameter = false)
        {
            ms.AddScalarType(typeof(VarBinary), DataType.VarBinary);
            ms.AddScalarType(typeof(VarChar), DataType.VarChar);
            ms.AddScalarType(typeof(NVarChar), DataType.NVarChar);

            if (!asDataParameter)
            {
                ms.SetConvertExpression <string, VarChar>  (v => new VarChar()
                {
                    Value = v
                });
                ms.SetConvertExpression <string, NVarChar> (v => new NVarChar()
                {
                    Value = v
                });
                ms.SetConvertExpression <byte[], VarBinary>(v => new VarBinary()
                {
                    Value = v
                });
                ms.SetConvertExpression <VarChar?, string?>  (v => v == null ? null : v.Value);
                ms.SetConvertExpression <NVarChar?, string?> (v => v == null ? null : v.Value);
                ms.SetConvertExpression <VarBinary?, byte[]?>(v => v == null ? null : v.Value);
            }
            else
            {
                ms.SetConvertExpression <string, VarChar>  (v => new VarChar()
                {
                    Value = v
                });
                ms.SetConvertExpression <string, NVarChar> (v => new NVarChar()
                {
                    Value = v
                });
                ms.SetConvertExpression <byte[], VarBinary>(v => new VarBinary()
                {
                    Value = v
                });
                ms.SetConvertExpression <VarChar?, DataParameter?>  (v => v == null ? null : DataParameter.VarChar(null, v.Value));
                ms.SetConvertExpression <NVarChar?, DataParameter?> (v => v == null ? null : DataParameter.NVarChar(null, v.Value));
                ms.SetConvertExpression <VarBinary?, DataParameter?>(v => v == null ? null : DataParameter.VarBinary(null, v.Value));
            }
        }
        private void AddUdtType(Type type)
        {
            if (type == null)
            {
                return;
            }

            if (!type.IsValueTypeEx())
            {
                MappingSchema.AddScalarType(type, null, true, DataType.Udt);
            }
            else
            {
                MappingSchema.AddScalarType(type, DataType.Udt);
                MappingSchema.AddScalarType(type.AsNullable(), null, true, DataType.Udt);
            }
        }
Esempio n. 9
0
        private static OracleProviderAdapter CreateAdapter(string assemblyName, string clientNamespace, string typesNamespace, string?factoryName)
        {
            var isNative = false;

#if NETFRAMEWORK
            isNative = assemblyName == NativeAssemblyName;
#endif

            var assembly = Common.Tools.TryLoadAssembly(assemblyName, factoryName);
            if (assembly == null)
            {
                throw new InvalidOperationException($"Cannot load assembly {assemblyName}");
            }

            var connectionType  = assembly.GetType($"{clientNamespace}.OracleConnection", true) !;
            var parameterType   = assembly.GetType($"{clientNamespace}.OracleParameter", true) !;
            var dataReaderType  = assembly.GetType($"{clientNamespace}.OracleDataReader", true) !;
            var transactionType = assembly.GetType($"{clientNamespace}.OracleTransaction", true) !;
            var dbType          = assembly.GetType($"{clientNamespace}.OracleDbType", true) !;
            var commandType     = assembly.GetType($"{clientNamespace}.OracleCommand", true) !;

            var mappingSchema = new MappingSchema();

            // do not set default conversion for BFile as it could be converted to file name, byte[], Stream and we don't know what user needs
            var oracleBFileType        = loadType("OracleBFile", DataType.BFile, skipConvertExpression: true) !;
            var oracleBinaryType       = loadType("OracleBinary", DataType.VarBinary) !;
            var oracleBlobType         = loadType("OracleBlob", DataType.Blob) !;
            var oracleClobType         = loadType("OracleClob", DataType.NText) !;
            var oracleDateType         = loadType("OracleDate", DataType.DateTime) !;
            var oracleDecimalType      = loadType("OracleDecimal", DataType.Decimal) !;
            var oracleIntervalDSType   = loadType("OracleIntervalDS", DataType.Time) !;
            var oracleIntervalYMType   = loadType("OracleIntervalYM", DataType.Date) !;
            var oracleStringType       = loadType("OracleString", DataType.NVarChar) !;
            var oracleTimeStampType    = loadType("OracleTimeStamp", DataType.DateTime2) !;
            var oracleTimeStampLTZType = loadType("OracleTimeStampLTZ", DataType.DateTimeOffset) !;
            var oracleTimeStampTZType  = loadType("OracleTimeStampTZ", DataType.DateTimeOffset) !;
            var oracleXmlTypeType      = loadType("OracleXmlType", DataType.Xml) !;
            var oracleXmlStreamType    = loadType("OracleXmlStream", DataType.Xml, true, false) !;
            var oracleRefCursorType    = loadType("OracleRefCursor", DataType.Binary, hasValue: false) !;
            var oracleRefType          = loadType("OracleRef", DataType.Binary, true);

            BulkCopyAdapter?bulkCopy   = null;
            var             typeMapper = new TypeMapper();

            typeMapper.RegisterTypeWrapper <OracleConnection>(connectionType);
            typeMapper.RegisterTypeWrapper <OracleParameter>(parameterType);
            typeMapper.RegisterTypeWrapper <OracleDbType>(dbType);
            typeMapper.RegisterTypeWrapper <OracleCommand>(commandType);
            typeMapper.RegisterTypeWrapper <OracleDataReader>(dataReaderType);
            typeMapper.RegisterTypeWrapper <OracleTimeStampTZ>(oracleTimeStampTZType);
            typeMapper.RegisterTypeWrapper <OracleTimeStampLTZ>(oracleTimeStampLTZType);
            typeMapper.RegisterTypeWrapper <OracleDecimal>(oracleDecimalType);

            if (isNative)
            {
                var bulkCopyType                        = assembly.GetType($"{clientNamespace}.OracleBulkCopy", true) !;
                var bulkCopyOptionsType                 = assembly.GetType($"{clientNamespace}.OracleBulkCopyOptions", true) !;
                var bulkRowsCopiedEventHandlerType      = assembly.GetType($"{clientNamespace}.OracleRowsCopiedEventHandler", true) !;
                var bulkCopyColumnMappingType           = assembly.GetType($"{clientNamespace}.OracleBulkCopyColumnMapping", true) !;
                var bulkCopyColumnMappingCollectionType = assembly.GetType($"{clientNamespace}.OracleBulkCopyColumnMappingCollection", true) !;
                var rowsCopiedEventArgsType             = assembly.GetType($"{clientNamespace}.OracleRowsCopiedEventArgs", true) !;

                // bulk copy types
                typeMapper.RegisterTypeWrapper <OracleBulkCopy>(bulkCopyType);
                typeMapper.RegisterTypeWrapper <OracleBulkCopyOptions>(bulkCopyOptionsType);
                typeMapper.RegisterTypeWrapper <OracleRowsCopiedEventHandler>(bulkRowsCopiedEventHandlerType);
                typeMapper.RegisterTypeWrapper <OracleBulkCopyColumnMapping>(bulkCopyColumnMappingType);
                typeMapper.RegisterTypeWrapper <OracleBulkCopyColumnMappingCollection>(bulkCopyColumnMappingCollectionType);
                typeMapper.RegisterTypeWrapper <OracleRowsCopiedEventArgs>(rowsCopiedEventArgsType);
                typeMapper.FinalizeMappings();

                bulkCopy = new BulkCopyAdapter(
                    typeMapper.BuildWrappedFactory((IDbConnection connection, OracleBulkCopyOptions options) => new OracleBulkCopy((OracleConnection)connection, options)),
                    typeMapper.BuildWrappedFactory((int source, string destination) => new OracleBulkCopyColumnMapping(source, destination)));
            }
            else
            {
                typeMapper.FinalizeMappings();
            }

            var paramMapper      = typeMapper.Type <OracleParameter>();
            var dbTypeBuilder    = paramMapper.Member(p => p.OracleDbType);
            var connectionMapper = typeMapper.Type <OracleConnection>();
            var commandMapper    = typeMapper.Type <OracleCommand>();

            // data reader expressions
            // rd.GetOracleTimeStampTZ(i) => DateTimeOffset
            var generator    = new ExpressionGenerator(typeMapper);
            var rdParam      = Expression.Parameter(typeof(IDataReader), "rd");
            var indexParam   = Expression.Parameter(typeof(int), "i");
            var tstzExpr     = generator.MapExpression((IDataReader rd, int i) => ((OracleDataReader)rd).GetOracleTimeStampTZ(i), rdParam, indexParam);
            var tstzVariable = generator.AssignToVariable(tstzExpr, "tstz");
            var expr         = generator.MapExpression((OracleTimeStampTZ tstz) => new DateTimeOffset(
                                                           tstz.Year, tstz.Month, tstz.Day,
                                                           tstz.Hour, tstz.Minute, tstz.Second,
                                                           tstz.GetTimeZoneOffset()).AddTicks(tstz.Nanosecond / NanosecondsPerTick), tstzVariable);
            generator.AddExpression(expr);
            var body = generator.Build();
            var readDateTimeOffsetFromOracleTimeStampTZ = (Expression <Func <IDataReader, int, DateTimeOffset> >)Expression.Lambda(body, rdParam, indexParam);

            // rd.GetOracleTimeStampLTZ(i) => DateTimeOffset
            generator    = new ExpressionGenerator(typeMapper);
            tstzExpr     = generator.MapExpression((IDataReader rd, int i) => ((OracleDataReader)rd).GetOracleTimeStampLTZ(i).ToOracleTimeStampTZ(), rdParam, indexParam);
            tstzVariable = generator.AssignToVariable(tstzExpr, "tstz");
            expr         = generator.MapExpression((OracleTimeStampTZ tstz) => new DateTimeOffset(
                                                       tstz.Year, tstz.Month, tstz.Day,
                                                       tstz.Hour, tstz.Minute, tstz.Second,
                                                       tstz.GetTimeZoneOffset()).AddTicks(tstz.Nanosecond / NanosecondsPerTick), tstzVariable);
            generator.AddExpression(expr);
            body = generator.Build();
            var readDateTimeOffsetFromOracleTimeStampLTZ = (Expression <Func <IDataReader, int, DateTimeOffset> >)Expression.Lambda(body, rdParam, indexParam);

            // rd.GetOracleDecimal(i) => decimal
            generator = new ExpressionGenerator(typeMapper);
            var decExpr          = generator.MapExpression((IDataReader rd, int i) => ((OracleDataReader)rd).GetOracleDecimal(i), rdParam, indexParam);
            var oracleDecimalVar = generator.AssignToVariable(decExpr, "dec");
            var precision        = generator.AssignToVariable(Expression.Constant(29), "precision");
            var decimalVar       = generator.AddVariable(Expression.Parameter(typeof(decimal), "dec"));
            var label            = Expression.Label(typeof(decimal));

            generator.AddExpression(
                Expression.Loop(
                    Expression.TryCatch(
                        Expression.Block(
                            Expression.Assign(oracleDecimalVar, generator.MapExpression((OracleDecimal d, int p) => OracleDecimal.SetPrecision(d, p), oracleDecimalVar, precision)),
                            Expression.Assign(decimalVar, Expression.Convert(oracleDecimalVar, typeof(decimal))),
                            Expression.Break(label, decimalVar)),
                        Expression.Catch(
                            typeof(OverflowException),
                            Expression.Block(
                                Expression.IfThen(
                                    Expression.LessThanOrEqual(Expression.SubtractAssign(precision, Expression.Constant(1)), Expression.Constant(26)),
                                    Expression.Rethrow())))),
                    label));

            body = generator.Build();

            var readOracleDecimalToDecimalAdv = (Expression <Func <IDataReader, int, decimal> >)Expression.Lambda(body, rdParam, indexParam);
            // workaround for mapper issue with complex reader expressions handling
            // https://github.com/linq2db/linq2db/issues/2032
            var compiledReader = readOracleDecimalToDecimalAdv.Compile();
            readOracleDecimalToDecimalAdv = (Expression <Func <IDataReader, int, decimal> >)Expression.Lambda(
                Expression.Invoke(Expression.Constant(compiledReader), rdParam, indexParam),
                rdParam,
                indexParam);

            var readOracleDecimalToInt     = (Expression <Func <IDataReader, int, int> >)typeMapper.MapLambda <IDataReader, int, int>((rd, i) => (int)(decimal)OracleDecimal.SetPrecision(((OracleDataReader)rd).GetOracleDecimal(i), 27));
            var readOracleDecimalToLong    = (Expression <Func <IDataReader, int, long> >)typeMapper.MapLambda <IDataReader, int, long>((rd, i) => (long)(decimal)OracleDecimal.SetPrecision(((OracleDataReader)rd).GetOracleDecimal(i), 27));
            var readOracleDecimalToDecimal = (Expression <Func <IDataReader, int, decimal> >)typeMapper.MapLambda <IDataReader, int, decimal>((rd, i) => (decimal)OracleDecimal.SetPrecision(((OracleDataReader)rd).GetOracleDecimal(i), 27));

            return(new OracleProviderAdapter(
                       connectionType,
                       dataReaderType,
                       parameterType,
                       commandType,
                       transactionType,
                       mappingSchema,

                       oracleBFileType,
                       oracleBinaryType,
                       oracleBlobType,
                       oracleClobType,
                       oracleDateType,
                       oracleDecimalType,
                       oracleIntervalDSType,
                       oracleIntervalYMType,
                       oracleStringType,
                       oracleTimeStampType,
                       oracleTimeStampLTZType,
                       oracleTimeStampTZType,
                       oracleXmlTypeType,
                       oracleXmlStreamType,
                       oracleRefCursorType,
                       oracleRefType,

                       typeMapper.BuildWrappedFactory((string connectionString) => new OracleConnection(connectionString)),

                       typesNamespace,

                       dbTypeBuilder.BuildSetter <IDbDataParameter>(),
                       dbTypeBuilder.BuildGetter <IDbDataParameter>(),

                       connectionMapper.Member(c => c.HostName).BuildGetter <IDbConnection>(),
                       connectionMapper.Member(c => c.DatabaseName).BuildGetter <IDbConnection>(),


                       commandMapper.Member(p => p.BindByName).BuildSetter <IDbCommand>(),
                       commandMapper.Member(p => p.ArrayBindCount).BuildSetter <IDbCommand>(),
                       commandMapper.Member(p => p.InitialLONGFetchSize).BuildSetter <IDbCommand>(),

                       typeMapper.BuildFactory((DateTimeOffset dto, string offset) => new OracleTimeStampTZ(dto.Year, dto.Month, dto.Day, dto.Hour, dto.Minute, dto.Second, GetDateTimeOffsetNanoseconds(dto), offset)),

                       readDateTimeOffsetFromOracleTimeStampTZ,
                       readDateTimeOffsetFromOracleTimeStampLTZ,
                       readOracleDecimalToDecimalAdv,
                       readOracleDecimalToInt,
                       readOracleDecimalToLong,
                       readOracleDecimalToDecimal,
                       bulkCopy));

            Type?loadType(string typeName, DataType dataType, bool optional = false, bool hasNull = true, bool hasValue = true, bool skipConvertExpression = false)
            {
                var type = assembly !.GetType($"{typesNamespace}.{typeName}", !optional);

                if (type == null)
                {
                    return(null);
                }

                if (hasNull)
                {
                    // if native provider fails here, check that you have ODAC installed properly
                    var getNullValue = Expression.Lambda <Func <object> >(Expression.Convert(ExpressionHelper.Field(type, "Null"), typeof(object))).Compile();
                    mappingSchema.AddScalarType(type, getNullValue(), true, dataType);
                }
                else
                {
                    mappingSchema.AddScalarType(type, null, true, dataType);
                }

                if (skipConvertExpression)
                {
                    return(type);
                }

                // conversion from provider-specific type
                var valueParam = Expression.Parameter(type);

                Expression memberExpression;

                if (!hasValue)
                {
                    memberExpression = valueParam;
                }
                else
                {
                    memberExpression = ExpressionHelper.Property(valueParam, "Value");
                }

                var condition = Expression.Condition(
                    Expression.Equal(valueParam, ExpressionHelper.Field(type, "Null")),
                    Expression.Constant(null, typeof(object)),
                    Expression.Convert(memberExpression, typeof(object)));

                var convertExpression = Expression.Lambda(condition, valueParam);

                mappingSchema.SetConvertExpression(type, typeof(object), convertExpression);

                return(type);
            }
        }
Esempio n. 10
0
        protected override void OnConnectionTypeCreated(Type connectionType)
        {
            var typesNamespace = AssemblyName + ".Types.";

            _oracleBFile        = connectionType.Assembly.GetType(typesNamespace + "OracleBFile", true);
            _oracleBinary       = connectionType.Assembly.GetType(typesNamespace + "OracleBinary", true);
            _oracleBlob         = connectionType.Assembly.GetType(typesNamespace + "OracleBlob", true);
            _oracleClob         = connectionType.Assembly.GetType(typesNamespace + "OracleClob", true);
            _oracleDate         = connectionType.Assembly.GetType(typesNamespace + "OracleDate", true);
            _oracleDecimal      = connectionType.Assembly.GetType(typesNamespace + "OracleDecimal", true);
            _oracleIntervalDS   = connectionType.Assembly.GetType(typesNamespace + "OracleIntervalDS", true);
            _oracleIntervalYM   = connectionType.Assembly.GetType(typesNamespace + "OracleIntervalYM", true);
            _oracleRefCursor    = connectionType.Assembly.GetType(typesNamespace + "OracleRefCursor", true);
            _oracleString       = connectionType.Assembly.GetType(typesNamespace + "OracleString", true);
            _oracleTimeStamp    = connectionType.Assembly.GetType(typesNamespace + "OracleTimeStamp", true);
            _oracleTimeStampLTZ = connectionType.Assembly.GetType(typesNamespace + "OracleTimeStampLTZ", true);
            _oracleTimeStampTZ  = connectionType.Assembly.GetType(typesNamespace + "OracleTimeStampTZ", true);
            _oracleRef          = connectionType.Assembly.GetType(typesNamespace + "OracleRef", false);
            _oracleXmlType      = connectionType.Assembly.GetType(typesNamespace + "OracleXmlType", false);
            _oracleXmlStream    = connectionType.Assembly.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.Call(
                        MemberHelper.MethodOf(() => ToDateTimeOffset(null)),
                        Expression.Convert(tstz, typeof(object))
                        )
                }),
                        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.Call(
                        MemberHelper.MethodOf(() => ToDateTimeOffset(null)),
                        Expression.Convert(tstz, typeof(object))
                        )
                }),
                        dataReaderParameter,
                        indexParameter);
            }

            {
                // ((OracleCommand)dataConnection.Command).BindByName = true;

                var p = Expression.Parameter(typeof(DataConnection), "dataConnection");

                _setBindByName =
                    Expression.Lambda <Action <DataConnection> >(
                        Expression.Assign(
                            Expression.PropertyOrField(
                                Expression.Convert(
                                    Expression.PropertyOrField(p, "Command"),
                                    connectionType.Assembly.GetType(AssemblyName + ".Client.OracleCommand", true)),
                                "BindByName"),
                            Expression.Constant(true)),
                        p
                        ).Compile();
            }

            {
                // 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.GetConstructor(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);                 // ?
            }
        }
Esempio n. 11
0
        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));
            }
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
0
        protected override void OnConnectionTypeCreated(Type connectionType)
        {
            DB2Types.ConnectionType = connectionType;

            DB2Types.DB2Int64.Type        = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2Int64", true);
            DB2Types.DB2Int32.Type        = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2Int32", true);
            DB2Types.DB2Int16.Type        = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2Int16", true);
            DB2Types.DB2Decimal.Type      = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2Decimal", true);
            DB2Types.DB2DecimalFloat.Type = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2DecimalFloat", true);
            DB2Types.DB2Real.Type         = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2Real", true);
            DB2Types.DB2Real370.Type      = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2Real370", true);
            DB2Types.DB2Double.Type       = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2Double", true);
            DB2Types.DB2String.Type       = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2String", true);
            DB2Types.DB2Clob.Type         = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2Clob", true);
            DB2Types.DB2Binary.Type       = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2Binary", true);
            DB2Types.DB2Blob.Type         = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2Blob", true);
            DB2Types.DB2Date.Type         = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2Date", true);
            DB2Types.DB2Time.Type         = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2Time", true);
            DB2Types.DB2TimeStamp.Type    = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2TimeStamp", true);
            DB2Types.DB2Xml           = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2Xml", true);
            DB2Types.DB2RowId.Type    = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2RowId", true);
            DB2Types.DB2DateTime.Type = connectionType.AssemblyEx().GetType("IBM.Data.DB2Types.DB2DateTime", false);

            SetProviderField(DB2Types.DB2Int64, typeof(Int64), "GetDB2Int64");
            SetProviderField(DB2Types.DB2Int32, typeof(Int32), "GetDB2Int32");
            SetProviderField(DB2Types.DB2Int16, typeof(Int16), "GetDB2Int16");
            SetProviderField(DB2Types.DB2Decimal, typeof(Decimal), "GetDB2Decimal");
            SetProviderField(DB2Types.DB2DecimalFloat, typeof(Decimal), "GetDB2DecimalFloat");
            SetProviderField(DB2Types.DB2Real, typeof(Single), "GetDB2Real");
            SetProviderField(DB2Types.DB2Real370, typeof(Single), "GetDB2Real370");
            SetProviderField(DB2Types.DB2Double, typeof(Double), "GetDB2Double");
            SetProviderField(DB2Types.DB2String, typeof(String), "GetDB2String");
            SetProviderField(DB2Types.DB2Clob, typeof(String), "GetDB2Clob");
            SetProviderField(DB2Types.DB2Binary, typeof(byte[]), "GetDB2Binary");
            SetProviderField(DB2Types.DB2Blob, typeof(byte[]), "GetDB2Blob");
            SetProviderField(DB2Types.DB2Date, typeof(DateTime), "GetDB2Date");
            SetProviderField(DB2Types.DB2Time, typeof(TimeSpan), "GetDB2Time");
            SetProviderField(DB2Types.DB2TimeStamp, typeof(DateTime), "GetDB2TimeStamp");
            SetProviderField(DB2Types.DB2Xml, typeof(string), "GetDB2Xml");
            SetProviderField(DB2Types.DB2RowId, typeof(byte[]), "GetDB2RowId");

            MappingSchema.AddScalarType(DB2Types.DB2Int64, GetNullValue(DB2Types.DB2Int64), true, DataType.Int64);
            MappingSchema.AddScalarType(DB2Types.DB2Int32, GetNullValue(DB2Types.DB2Int32), true, DataType.Int32);
            MappingSchema.AddScalarType(DB2Types.DB2Int16, GetNullValue(DB2Types.DB2Int16), true, DataType.Int16);
            MappingSchema.AddScalarType(DB2Types.DB2Decimal, GetNullValue(DB2Types.DB2Decimal), true, DataType.Decimal);
            MappingSchema.AddScalarType(DB2Types.DB2DecimalFloat, GetNullValue(DB2Types.DB2DecimalFloat), true, DataType.Decimal);
            MappingSchema.AddScalarType(DB2Types.DB2Real, GetNullValue(DB2Types.DB2Real), true, DataType.Single);
            MappingSchema.AddScalarType(DB2Types.DB2Real370, GetNullValue(DB2Types.DB2Real370), true, DataType.Single);
            MappingSchema.AddScalarType(DB2Types.DB2Double, GetNullValue(DB2Types.DB2Double), true, DataType.Double);
            MappingSchema.AddScalarType(DB2Types.DB2String, GetNullValue(DB2Types.DB2String), true, DataType.NVarChar);
            MappingSchema.AddScalarType(DB2Types.DB2Clob, GetNullValue(DB2Types.DB2Clob), true, DataType.NText);
            MappingSchema.AddScalarType(DB2Types.DB2Binary, GetNullValue(DB2Types.DB2Binary), true, DataType.VarBinary);
            MappingSchema.AddScalarType(DB2Types.DB2Blob, GetNullValue(DB2Types.DB2Blob), true, DataType.Blob);
            MappingSchema.AddScalarType(DB2Types.DB2Date, GetNullValue(DB2Types.DB2Date), true, DataType.Date);
            MappingSchema.AddScalarType(DB2Types.DB2Time, GetNullValue(DB2Types.DB2Time), true, DataType.Time);
            MappingSchema.AddScalarType(DB2Types.DB2TimeStamp, GetNullValue(DB2Types.DB2TimeStamp), true, DataType.DateTime2);
            MappingSchema.AddScalarType(DB2Types.DB2RowId, GetNullValue(DB2Types.DB2RowId), true, DataType.VarBinary);
            MappingSchema.AddScalarType(DB2Types.DB2Xml, DB2Tools.IsCore ? null : GetNullValue(DB2Types.DB2Xml), true, DataType.Xml);

            _setBlob = GetSetParameter(connectionType, "DB2Parameter", "DB2Type", "DB2Type", "Blob");

            if (DB2Types.DB2DateTime.IsSupported)
            {
                SetProviderField(DB2Types.DB2DateTime, typeof(DateTime), "GetDB2DateTime");
                MappingSchema.AddScalarType(DB2Types.DB2DateTime, GetNullValue(DB2Types.DB2DateTime), true, DataType.DateTime);
            }

            if (DataConnection.TraceSwitch.TraceInfo)
            {
                DataConnection.WriteTraceLine(
                    DataReaderType.AssemblyEx().FullName,
                    DataConnection.TraceSwitch.DisplayName);

                DataConnection.WriteTraceLine(
                    DB2Types.DB2DateTime.IsSupported ? "DB2DateTime is supported." : "DB2DateTime is not supported.",
                    DataConnection.TraceSwitch.DisplayName);
            }

            DB2Tools.Initialized();
        }
Esempio n. 15
0
        protected override void OnConnectionTypeCreated(Type connectionType)
        {
            var typesNamespace = 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,
                //         TimeSpan.Parse(tstz.TimeZone.TrimStart('+'))).AddTicks(tstz.Nanosecond / NanosecondsPerTick);
                // }

                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.Call(
                        MemberHelper.MethodOf(() => ToDateTimeOffset(null)),
                        Expression.Convert(tstz, typeof(object))
                        )
                }),
                        dataReaderParameter,
                        indexParameter);
            }

            {
                // static decimal GetOracleDecimal(OracleDataReader rd, int idx)
                // {
                //     var tstz = rd.GetOracleDecimal(idx);
                //     decimal decimalVar;
                //     var precision = 29;
                //     while (true)
                //     {
                //        try
                //        {
                //           tstz = OracleDecimal.SetPrecision(tstz, precision);
                //           decimalVar = (decimal)tstz;
                //           break;
                //        }
                //        catch(OverflowException exceptionVar)
                //        {
                //           if (--precision <= 26)
                //              throw exceptionVar;
                //        }
                //     }
                //
                //     return decimalVar;
                // }

                var tstz               = Expression.Parameter(_oracleDecimal, "tstz");
                var decimalVar         = Expression.Variable(typeof(decimal), "decimalVar");
                var precision          = Expression.Variable(typeof(int), "precision");
                var label              = Expression.Label(typeof(decimal));
                var setPrecisionMethod = _oracleDecimal.GetMethod("SetPrecision", BindingFlags.Static | BindingFlags.Public);

                var getDecimalAdv = Expression.Lambda(
                    Expression.Block(
                        new[] { tstz, decimalVar, precision },
                        Expression.Assign(tstz, Expression.Call(dataReaderParameter, "GetOracleDecimal", null, indexParameter)),
                        Expression.Assign(precision, Expression.Constant(29)),
                        Expression.Loop(
                            Expression.TryCatch(
                                Expression.Block(
                                    Expression.Assign(tstz, Expression.Call(setPrecisionMethod, tstz, precision)),
                                    Expression.Assign(decimalVar, Expression.Convert(tstz, typeof(decimal))),
                                    Expression.Break(label, decimalVar)
                                    ),
                                Expression.Catch(typeof(OverflowException),
                                                 Expression.Block(
                                                     Expression.IfThen(
                                                         Expression.LessThanOrEqual(Expression.SubtractAssign(precision, Expression.Constant(1)),
                                                                                    Expression.Constant(26)),
                                                         Expression.Rethrow()
                                                         )
                                                     )
                                                 )
                                ),
                            label),
                        decimalVar
                        ),
                    dataReaderParameter,
                    indexParameter);


                // static T GetDecimalValue<T>(OracleDataReader rd, int idx)
                // {
                //    return (T)(decimal)OracleDecimal.SetPrecision(rd.GetOracleDecimal(idx), 27);
                // }

                LambdaExpression GetDecimal(Type t, bool convToDecimal)
                {
                    Expression expr =
                        Expression.Call(setPrecisionMethod,
                                        Expression.Call(
                                            dataReaderParameter,
                                            "GetOracleDecimal",
                                            null,
                                            indexParameter),
                                        Expression.Constant(27));

                    if (convToDecimal)
                    {
                        expr = Expression.Convert(expr, typeof(decimal));
                    }

                    return(Expression.Lambda(
                               Expression.Convert(expr, t),
                               dataReaderParameter,
                               indexParameter));
                }

                // workaround for mapper issue with complex reader expressions handling
                // https://github.com/linq2db/linq2db/issues/2032
                var compiledReader = getDecimalAdv.Compile();

                var getDecimalAdvFixed = Expression.Lambda(
                    Expression.Invoke(Expression.Constant(compiledReader), dataReaderParameter, indexParameter),
                    dataReaderParameter,
                    indexParameter);

                ReaderExpressions[new ReaderInfo {
                                      ToType = typeof(decimal), ProviderFieldType = _oracleDecimal
                                  }] = getDecimalAdvFixed;
                ReaderExpressions[new ReaderInfo {
                                      ToType = typeof(decimal), FieldType = typeof(decimal)
                                  }] = getDecimalAdvFixed;
                ReaderExpressions[new ReaderInfo {
                                      ToType = typeof(int), FieldType = typeof(decimal)
                                  }] = GetDecimal(typeof(int), true);
                ReaderExpressions[new ReaderInfo {
                                      ToType = typeof(long), FieldType = typeof(decimal)
                                  }] = GetDecimal(typeof(long), true);
                ReaderExpressions[new ReaderInfo {
                                      FieldType = typeof(decimal)
                                  }] = GetDecimal(typeof(decimal), false);
            }

            {
                // 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,
                //         TimeSpan.Parse(tstz.TimeZone.TrimStart('+'))).AddTicks(tstz.Nanosecond / NanosecondsPerTick);
                // }

                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.Call(
                        MemberHelper.MethodOf(() => ToDateTimeOffset(null)),
                        Expression.Convert(tstz, typeof(object))
                        )
                }),
                        dataReaderParameter,
                        indexParameter);
            }

            {
                // ((OracleCommand)dataConnection.Command).BindByName = true;

                var p     = Expression.Parameter(typeof(DataConnection), "dataConnection");
                var pbind = Expression.Parameter(typeof(bool), "value");

                _setBindByName =
                    Expression.Lambda <Action <DataConnection, bool> >(
                        Expression.Assign(
                            Expression.PropertyOrField(
                                Expression.Convert(
                                    Expression.Call(
                                        MemberHelper.MethodOf(() => Proxy.GetUnderlyingObject((DbCommand)null)),
                                        Expression.Convert(Expression.PropertyOrField(p, "Command"), typeof(DbCommand))),
                                    connectionType.AssemblyEx().GetType(AssemblyName + ".Client.OracleCommand", true)),
                                "BindByName"),
                            pbind),
                        p,
                        pbind
                        ).Compile();
            }

            {
                // value = new OracleTimeStampTZ(dto.Year, dto.Month, dto.Day, dto.Hour, dto.Minute, dto.Second, GetDateTimeOffsetNanoseconds(dto), 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.Call(null, MemberHelper.MethodOf(() => GetDateTimeOffsetNanoseconds(default(DateTimeOffset))), dto),
                                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");
            _setCursor         = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "RefCursor");
            _setNVarchar2      = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "NVarchar2");
            _setVarchar2       = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "Varchar2");
            _setLong           = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "Long");
            _setLongRaw        = GetSetParameter(connectionType, "OracleParameter", "OracleDbType", "OracleDbType", "LongRaw");

            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);                 // ?
            }
        }
Esempio n. 16
0
        private static InformixProviderAdapter CreateIfxAdapter()
        {
            var assembly = Common.Tools.TryLoadAssembly(IfxAssemblyName, IfxProviderFactoryName);

            if (assembly == null)
            {
                throw new InvalidOperationException($"Cannot load assembly {IfxAssemblyName}");
            }

            var connectionType  = assembly.GetType($"{IfxClientNamespace}.IfxConnection", true);
            var parameterType   = assembly.GetType($"{IfxClientNamespace}.IfxParameter", true);
            var dataReaderType  = assembly.GetType($"{IfxClientNamespace}.IfxDataReader", true);
            var commandType     = assembly.GetType($"{IfxClientNamespace}.IfxCommand", true);
            var transactionType = assembly.GetType($"{IfxClientNamespace}.IfxTransaction", true);
            var dbType          = assembly.GetType($"{IfxClientNamespace}.IfxType", true);

            var mappingSchema = new MappingSchema();
            var blobType      = loadType("IfxBlob", DataType.VarBinary) !;
            var clobType      = loadType("IfxClob", DataType.Text) !;
            var dateTimeType  = loadType("IfxDateTime", DataType.DateTime2) !;
            // those two types obsoleted in recent providers
            var decimalType  = loadType("IfxDecimal", DataType.Decimal) !;
            var timeSpanType = loadType("IfxTimeSpan", DataType.Time, true, true);

            var typeMapper = new TypeMapper();

            typeMapper.RegisterTypeWrapper <IfxConnection>(connectionType);
            typeMapper.RegisterTypeWrapper <IfxParameter>(parameterType);
            typeMapper.RegisterTypeWrapper <IfxType>(dbType);

            if (timeSpanType != null)
            {
                typeMapper.RegisterTypeWrapper <IfxTimeSpan>(timeSpanType);
            }

            // bulk copy exists only for IDS provider version
            BulkCopyAdapter?bulkCopy     = null;
            var             bulkCopyType = assembly.GetType($"{IfxClientNamespace}.IfxBulkCopy", false);

            if (bulkCopyType != null)
            {
                var bulkCopyOptionsType                 = assembly.GetType($"{IfxClientNamespace}.IfxBulkCopyOptions", true);
                var bulkRowsCopiedEventHandlerType      = assembly.GetType($"{IfxClientNamespace}.IfxRowsCopiedEventHandler", true);
                var bulkCopyColumnMappingType           = assembly.GetType($"{IfxClientNamespace}.IfxBulkCopyColumnMapping", true);
                var bulkCopyColumnMappingCollectionType = assembly.GetType($"{IfxClientNamespace}.IfxBulkCopyColumnMappingCollection", true);
                var rowsCopiedEventArgsType             = assembly.GetType($"{IfxClientNamespace}.IfxRowsCopiedEventArgs", true);

                typeMapper.RegisterTypeWrapper <IfxBulkCopy>(bulkCopyType);
                typeMapper.RegisterTypeWrapper <IfxBulkCopyOptions>(bulkCopyOptionsType);
                typeMapper.RegisterTypeWrapper <IfxRowsCopiedEventHandler>(bulkRowsCopiedEventHandlerType);
                typeMapper.RegisterTypeWrapper <IfxBulkCopyColumnMapping>(bulkCopyColumnMappingType);
                typeMapper.RegisterTypeWrapper <IfxBulkCopyColumnMappingCollection>(bulkCopyColumnMappingCollectionType);
                typeMapper.RegisterTypeWrapper <IfxRowsCopiedEventArgs>(rowsCopiedEventArgsType);

                typeMapper.FinalizeMappings();

                bulkCopy = new BulkCopyAdapter(
                    typeMapper.BuildWrappedFactory((IDbConnection connection, IfxBulkCopyOptions options) => new IfxBulkCopy((IfxConnection)connection, options)),
                    typeMapper.BuildWrappedFactory((int source, string destination) => new IfxBulkCopyColumnMapping(source, destination)));
            }
            else
            {
                typeMapper.FinalizeMappings();
            }

            var paramMapper   = typeMapper.Type <IfxParameter>();
            var dbTypeBuilder = paramMapper.Member(p => p.IfxType);

            Func <TimeSpan, object>?timespanFactory = null;

            if (timeSpanType != null)
            {
                timespanFactory = typeMapper.BuildFactory((TimeSpan ts) => new IfxTimeSpan(ts));
            }

            return(new InformixProviderAdapter(
                       connectionType,
                       dataReaderType,
                       parameterType,
                       commandType,
                       transactionType,
                       mappingSchema,
                       blobType,
                       clobType,
                       decimalType,
                       dateTimeType,
                       timeSpanType,
                       dbTypeBuilder.BuildSetter <IDbDataParameter>(),
                       dbTypeBuilder.BuildGetter <IDbDataParameter>(),
                       timespanFactory,
                       bulkCopy));

            Type?loadType(string typeName, DataType dataType, bool optional = false, bool obsolete = false, bool register = true)
            {
                var type = assembly !.GetType($"{IfxTypesNamespace}.{typeName}", !optional);

                if (type == null)
                {
                    return(null);
                }

                if (obsolete && type.GetCustomAttributes(typeof(ObsoleteAttribute), false).Length > 0)
                {
                    return(null);
                }

                if (register)
                {
                    var getNullValue = Expression.Lambda <Func <object> >(Expression.Convert(ExpressionHelper.Field(type, "Null"), typeof(object))).Compile();
                    mappingSchema.AddScalarType(type, getNullValue(), true, dataType);
                }

                return(type);
            }
        }
Esempio n. 17
0
        public static DB2ProviderAdapter GetInstance()
        {
            if (_instance == null)
            {
                lock (_syncRoot)
                    if (_instance == null)
                    {
                        var assembly = Common.Tools.TryLoadAssembly(AssemblyName, ProviderFactoryName);
                        if (assembly == null)
                        {
                            throw new InvalidOperationException($"Cannot load assembly {AssemblyName}");
                        }

                        var connectionType  = assembly.GetType($"{ClientNamespace}.DB2Connection", true) !;
                        var parameterType   = assembly.GetType($"{ClientNamespace}.DB2Parameter", true) !;
                        var dataReaderType  = assembly.GetType($"{ClientNamespace}.DB2DataReader", true) !;
                        var transactionType = assembly.GetType($"{ClientNamespace}.DB2Transaction", true) !;
                        var commandType     = assembly.GetType($"{ClientNamespace}.DB2Command", true) !;
                        var dbType          = assembly.GetType($"{ClientNamespace}.DB2Type", true) !;
                        var serverTypesType = assembly.GetType($"{ClientNamespace}.DB2ServerTypes", true) !;

                        var bulkCopyType                    = assembly.GetType($"{ClientNamespace}.DB2BulkCopy", true) !;
                        var bulkCopyOptionsType             = assembly.GetType($"{ClientNamespace}.DB2BulkCopyOptions", true) !;
                        var bulkCopyColumnMappingType       = assembly.GetType($"{ClientNamespace}.DB2BulkCopyColumnMapping", true) !;
                        var rowsCopiedEventHandlerType      = assembly.GetType($"{ClientNamespace}.DB2RowsCopiedEventHandler", true) !;
                        var rowsCopiedEventArgs             = assembly.GetType($"{ClientNamespace}.DB2RowsCopiedEventArgs", true) !;
                        var bulkCopyColumnMappingCollection = assembly.GetType($"{ClientNamespace}.DB2BulkCopyColumnMappingCollection", true) !;


                        var mappingSchema = new MappingSchema();

                        var db2BinaryType       = loadType("DB2Binary", DataType.VarBinary) !;
                        var db2BlobType         = loadType("DB2Blob", DataType.Blob) !;
                        var db2ClobType         = loadType("DB2Clob", DataType.NText) !;
                        var db2DateType         = loadType("DB2Date", DataType.Date) !;
                        var db2DateTimeType     = loadType("DB2DateTime", DataType.DateTime, true);
                        var db2DecimalType      = loadType("DB2Decimal", DataType.Decimal) !;
                        var db2DecimalFloatType = loadType("DB2DecimalFloat", DataType.Decimal) !;
                        var db2DoubleType       = loadType("DB2Double", DataType.Double) !;
                        var db2Int16Type        = loadType("DB2Int16", DataType.Int16) !;
                        var db2Int32Type        = loadType("DB2Int32", DataType.Int32) !;
                        var db2Int64Type        = loadType("DB2Int64", DataType.Int64) !;
                        var db2RealType         = loadType("DB2Real", DataType.Single) !;
                        var db2Real370Type      = loadType("DB2Real370", DataType.Single) !;
                        var db2RowIdType        = loadType("DB2RowId", DataType.VarBinary) !;
                        var db2StringType       = loadType("DB2String", DataType.NVarChar) !;
                        var db2TimeType         = loadType("DB2Time", DataType.Time) !;
                        var db2TimeStampType    = loadType("DB2TimeStamp", DataType.DateTime2) !;
                        var db2XmlType          = loadType("DB2Xml", DataType.Xml) !;
                        var db2TimeSpanType     = loadType("DB2TimeSpan", DataType.Timestamp, true, true);

                        var typeMapper = new TypeMapper();

                        typeMapper.RegisterTypeWrapper <DB2ServerTypes>(serverTypesType);
                        typeMapper.RegisterTypeWrapper <DB2Connection>(connectionType);
                        typeMapper.RegisterTypeWrapper <DB2Parameter>(parameterType);
                        typeMapper.RegisterTypeWrapper <DB2Type>(dbType);
                        typeMapper.RegisterTypeWrapper <DB2Transaction>(transactionType);
                        typeMapper.RegisterTypeWrapper <DB2Binary>(db2BinaryType);

                        // bulk copy types
                        typeMapper.RegisterTypeWrapper <DB2BulkCopy>(bulkCopyType);
                        typeMapper.RegisterTypeWrapper <DB2RowsCopiedEventArgs>(rowsCopiedEventArgs);
                        typeMapper.RegisterTypeWrapper <DB2RowsCopiedEventHandler>(rowsCopiedEventHandlerType);
                        typeMapper.RegisterTypeWrapper <DB2BulkCopyColumnMappingCollection>(bulkCopyColumnMappingCollection);
                        typeMapper.RegisterTypeWrapper <DB2BulkCopyOptions>(bulkCopyOptionsType);
                        typeMapper.RegisterTypeWrapper <DB2BulkCopyColumnMapping>(bulkCopyColumnMappingType);

                        typeMapper.FinalizeMappings();

                        var db2BinaryBuilder = typeMapper.Type <DB2Binary>().Member(p => p.IsNull);
                        var isDB2BinaryNull  = db2BinaryBuilder.BuildGetter <object>();

                        var dbTypeBuilder = typeMapper.Type <DB2Parameter>().Member(p => p.DB2Type);
                        var typeSetter    = dbTypeBuilder.BuildSetter <IDbDataParameter>();
                        var typeGetter    = dbTypeBuilder.BuildGetter <IDbDataParameter>();


                        var bulkCopy = new BulkCopyAdapter(
                            typeMapper.BuildWrappedFactory((IDbConnection connection, DB2BulkCopyOptions options) => new DB2BulkCopy((DB2Connection)connection, options)),
                            typeMapper.BuildWrappedFactory((int source, string destination) => new DB2BulkCopyColumnMapping(source, destination)));


                        _instance = new DB2ProviderAdapter(
                            connectionType,
                            dataReaderType,
                            parameterType,
                            commandType,
                            transactionType,

                            db2DateTimeType,
                            db2BinaryType,
                            db2BlobType,
                            db2ClobType,
                            db2DateType,
                            db2DecimalType,
                            db2DecimalFloatType,
                            db2DoubleType,
                            db2Int16Type,
                            db2Int32Type,
                            db2Int64Type,
                            db2RealType,
                            db2Real370Type,
                            db2RowIdType,
                            db2StringType,
                            db2TimeType,
                            db2TimeStampType,
                            db2XmlType,
                            db2TimeSpanType,

                            mappingSchema,
                            typeSetter,
                            typeGetter,
                            typeMapper.BuildWrappedFactory((string connectionString) => new DB2Connection(connectionString)),
                            isDB2BinaryNull,
                            bulkCopy);

                        Type?loadType(string typeName, DataType dataType, bool optional = false, bool obsolete = false, bool register = true)
                        {
                            var type = assembly !.GetType($"{TypesNamespace}.{typeName}", !optional);

                            if (type == null)
                            {
                                return(null);
                            }

                            if (obsolete && type.GetCustomAttributes(typeof(ObsoleteAttribute), false).Length > 0)
                            {
                                return(null);
                            }

                            if (register)
                            {
                                var getNullValue = Expression.Lambda <Func <object> >(Expression.Convert(ExpressionHelper.Field(type, "Null"), typeof(object))).CompileExpression();
                                mappingSchema.AddScalarType(type, getNullValue(), true, dataType);
                            }

                            return(type);
                        }
                    }
            }

            return(_instance);
        }