internal static SapHanaProviderAdapter 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}.HanaConnection", true) !;
                        var dataReaderType  = assembly.GetType($"{ClientNamespace}.HanaDataReader", true) !;
                        var parameterType   = assembly.GetType($"{ClientNamespace}.HanaParameter", true) !;
                        var commandType     = assembly.GetType($"{ClientNamespace}.HanaCommand", true) !;
                        var transactionType = assembly.GetType($"{ClientNamespace}.HanaTransaction", true) !;
                        var dbType          = assembly.GetType($"{ClientNamespace}.HanaDbType", true) !;

                        var bulkCopyType                    = assembly.GetType($"{ClientNamespace}.HanaBulkCopy", true) !;
                        var bulkCopyOptionsType             = assembly.GetType($"{ClientNamespace}.HanaBulkCopyOptions", true) !;
                        var bulkCopyColumnMappingType       = assembly.GetType($"{ClientNamespace}.HanaBulkCopyColumnMapping", true) !;
                        var rowsCopiedEventHandlerType      = assembly.GetType($"{ClientNamespace}.HanaRowsCopiedEventHandler", true) !;
                        var rowsCopiedEventArgs             = assembly.GetType($"{ClientNamespace}.HanaRowsCopiedEventArgs", true) !;
                        var bulkCopyColumnMappingCollection = assembly.GetType($"{ClientNamespace}.HanaBulkCopyColumnMappingCollection", true) !;

                        var typeMapper = new TypeMapper();

                        typeMapper.RegisterTypeWrapper <HanaConnection>(connectionType);
                        typeMapper.RegisterTypeWrapper <HanaTransaction>(transactionType);
                        typeMapper.RegisterTypeWrapper <HanaParameter>(parameterType);
                        typeMapper.RegisterTypeWrapper <HanaDbType>(dbType);

                        // bulk copy types
                        typeMapper.RegisterTypeWrapper <HanaBulkCopy>(bulkCopyType);
                        typeMapper.RegisterTypeWrapper <HanaRowsCopiedEventArgs>(rowsCopiedEventArgs);
                        typeMapper.RegisterTypeWrapper <HanaRowsCopiedEventHandler>(rowsCopiedEventHandlerType);
                        typeMapper.RegisterTypeWrapper <HanaBulkCopyColumnMappingCollection>(bulkCopyColumnMappingCollection);
                        typeMapper.RegisterTypeWrapper <HanaBulkCopyOptions>(bulkCopyOptionsType);
                        typeMapper.RegisterTypeWrapper <HanaBulkCopyColumnMapping>(bulkCopyColumnMappingType);

                        typeMapper.FinalizeMappings();

                        var typeSetter = typeMapper.Type <HanaParameter>().Member(p => p.HanaDbType).BuildSetter <IDbDataParameter>();

                        _instance = new SapHanaProviderAdapter(
                            connectionType,
                            dataReaderType,
                            parameterType,
                            commandType,
                            transactionType,
                            typeSetter,
                            typeMapper.BuildWrappedFactory((IDbConnection connection, HanaBulkCopyOptions options, IDbTransaction? transaction) => new HanaBulkCopy((HanaConnection)connection, (HanaBulkCopyOptions)options, (HanaTransaction?)transaction)),
                            typeMapper.BuildWrappedFactory((int source, string destination) => new HanaBulkCopyColumnMapping(source, destination)));
                    }
            }

            return(_instance);
        }
        public static SqlCeProviderAdapter 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}.SqlCeConnection", true) !;
                        var dataReaderType  = assembly.GetType($"{ClientNamespace}.SqlCeDataReader", true) !;
                        var parameterType   = assembly.GetType($"{ClientNamespace}.SqlCeParameter", true) !;
                        var commandType     = assembly.GetType($"{ClientNamespace}.SqlCeCommand", true) !;
                        var transactionType = assembly.GetType($"{ClientNamespace}.SqlCeTransaction", true) !;
                        var sqlCeEngine     = assembly.GetType($"{ClientNamespace}.SqlCeEngine", true) !;

                        var typeMapper = new TypeMapper();
                        typeMapper.RegisterTypeWrapper <SqlCeEngine>(sqlCeEngine);
                        typeMapper.RegisterTypeWrapper <SqlCeParameter>(parameterType);
                        typeMapper.FinalizeMappings();

                        var dbTypeBuilder = typeMapper.Type <SqlCeParameter>().Member(p => p.SqlDbType);
                        var typeSetter    = dbTypeBuilder.BuildSetter <DbParameter>();
                        var typeGetter    = dbTypeBuilder.BuildGetter <DbParameter>();

                        _instance = new SqlCeProviderAdapter(
                            connectionType,
                            dataReaderType,
                            parameterType,
                            commandType,
                            transactionType,
                            typeSetter,
                            typeGetter,
                            typeMapper.BuildWrappedFactory((string connectionString) => new SqlCeEngine(connectionString)) !);
                    }
            }

            return(_instance);
        }
Exemple #3
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);
        }
Exemple #4
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);
            }
        }
Exemple #5
0
        public static DB2iSeriesAccessClientProviderAdapter 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}.iDB2Connection", true);
                        var parameterType   = assembly.GetType($"{ClientNamespace}.iDB2Parameter", true);
                        var dataReaderType  = assembly.GetType($"{ClientNamespace}.iDB2DataReader", true);
                        var transactionType = assembly.GetType($"{ClientNamespace}.iDB2Transaction", true);
                        var commandType     = assembly.GetType($"{ClientNamespace}.iDB2Command", true);
                        var dbType          = assembly.GetType($"{ClientNamespace}.iDB2DbType", true);

                        var mappingSchema = new MappingSchema();

                        var iDB2BigIntType         = loadType("iDB2BigInt", DataType.Int64);
                        var iDB2BinaryType         = loadType("iDB2Binary", DataType.Binary);
                        var iDB2BlobType           = loadType("iDB2Blob", DataType.Blob);
                        var iDB2CharType           = loadType("iDB2Char", DataType.Char);
                        var iDB2CharBitDataType    = loadType("iDB2CharBitData", DataType.Binary);
                        var iDB2ClobType           = loadType("iDB2Clob", DataType.Text);
                        var iDB2DataLinkType       = loadType("iDB2DataLink", DataType.NText);
                        var iDB2DateType           = loadType("iDB2Date", DataType.Date);
                        var iDB2DbClobType         = loadType("iDB2DbClob", DataType.NText);
                        var iDB2DecFloat16Type     = loadType("iDB2DecFloat16", DataType.Decimal);
                        var iDB2DecFloat34Type     = loadType("iDB2DecFloat34", DataType.Decimal);
                        var iDB2DecimalType        = loadType("iDB2Decimal", DataType.Decimal);
                        var iDB2DoubleType         = loadType("iDB2Double", DataType.Double);
                        var iDB2GraphicType        = loadType("iDB2Graphic", DataType.NChar);
                        var iDB2IntegerType        = loadType("iDB2Integer", DataType.Int32);
                        var iDB2NumericType        = loadType("iDB2Numeric", DataType.Decimal);
                        var iDB2RealType           = loadType("iDB2Real", DataType.Single);
                        var iDB2RowidType          = loadType("iDB2Rowid", DataType.VarBinary);
                        var iDB2SmallIntType       = loadType("iDB2SmallInt", DataType.Int16);
                        var iDB2TimeType           = loadType("iDB2Time", DataType.Time);
                        var iDB2TimeStampType      = loadType("iDB2TimeStamp", DataType.DateTime2);
                        var iDB2VarBinaryType      = loadType("iDB2VarBinary", DataType.VarBinary);
                        var iDB2VarCharType        = loadType("iDB2VarChar", DataType.VarChar);
                        var iDB2VarCharBitDataType = loadType("iDB2VarCharBitData", DataType.VarBinary);
                        var iDB2VarGraphicType     = loadType("iDB2VarGraphic", DataType.NVarChar);
                        var iDB2XmlType            = loadType("iDB2Xml", DataType.Xml);

                        var typeMapper = new TypeMapper();

                        typeMapper.RegisterTypeWrapper <iDB2Connection>(connectionType);
                        typeMapper.RegisterTypeWrapper <iDB2Parameter>(parameterType);
                        typeMapper.RegisterTypeWrapper <iDB2DbType>(dbType);

                        typeMapper.FinalizeMappings();

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

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

                            iDB2BigIntType,
                            iDB2BinaryType,
                            iDB2BlobType,
                            iDB2CharType,
                            iDB2CharBitDataType,
                            iDB2ClobType,
                            iDB2DataLinkType,
                            iDB2DateType,
                            iDB2DbClobType,
                            iDB2DecFloat16Type,
                            iDB2DecFloat34Type,
                            iDB2DecimalType,
                            iDB2DoubleType,
                            iDB2GraphicType,
                            iDB2IntegerType,
                            iDB2NumericType,
                            iDB2RealType,
                            iDB2RowidType,
                            iDB2SmallIntType,
                            iDB2TimeType,
                            iDB2TimeStampType,
                            iDB2VarBinaryType,
                            iDB2VarCharType,
                            iDB2VarCharBitDataType,
                            iDB2VarGraphicType,
                            iDB2XmlType,

                            mappingSchema,

                            typeSetter,
                            typeGetter,
                            typeMapper.BuildWrappedFactory((string connectionString) => new iDB2Connection(connectionString)),
                            typeMapper.BuildFunc <IDbConnection, string>(typeMapper.MapLambda((iDB2Connection conn) => conn.LibraryList)),
                            typeMapper.BuildFunc <IDbConnection, iDB2NamingConvention>(typeMapper.MapLambda((iDB2Connection conn) => conn.Naming)),

                            buildActionInvoker(commandType, "DeriveParameters"),
                            buildActionInvoker(commandType, "AddBatch")
                            );

                        DataConnection.WriteTraceLine(assembly.FullName, nameof(DB2iSeriesAccessClientProviderAdapter), System.Diagnostics.TraceLevel.Info);
            internal static MySqlProviderAdapter CreateAdapter()
            {
                var assembly = Common.Tools.TryLoadAssembly(MySqlConnectorAssemblyName, null);

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

                var hasBulkCopy  = assembly.GetName().Version >= MinBulkCopyVersion;
                var version1plus = assembly.GetName().Version >= MinModernVersion;

                var clientNamespace = version1plus ? MySqlConnectorNamespace      : OldMySqlConnectorNamespace;
                var typesNamespace  = version1plus ? MySqlConnectorTypesNamespace : OldMySqlConnectorTypesNamespace;

                var connectionType    = assembly.GetType($"{clientNamespace}.MySqlConnection", true) !;
                var dataReaderType    = assembly.GetType($"{clientNamespace}.MySqlDataReader", true) !;
                var parameterType     = assembly.GetType($"{clientNamespace}.MySqlParameter", true) !;
                var commandType       = assembly.GetType($"{clientNamespace}.MySqlCommand", true) !;
                var transactionType   = assembly.GetType($"{clientNamespace}.MySqlTransaction", true) !;
                var dbType            = assembly.GetType($"{clientNamespace}.MySqlDbType", true) !;
                var mySqlDateTimeType = assembly.GetType($"{typesNamespace}.MySqlDateTime", true) !;
                var mySqlGeometryType = assembly.GetType($"{typesNamespace}.MySqlGeometry", true) !;

                var typeMapper = new TypeMapper();

                typeMapper.RegisterTypeWrapper <MySqlParameter>(parameterType);
                typeMapper.RegisterTypeWrapper <MySqlDbType>(dbType);
                typeMapper.RegisterTypeWrapper <MySqlDateTime>(mySqlDateTimeType);

                typeMapper.RegisterTypeWrapper <MySqlConnection>(connectionType);
                typeMapper.RegisterTypeWrapper <MySqlTransaction>(transactionType);

                BulkCopyAdapter?bulkCopy = null;

                if (hasBulkCopy)
                {
                    var bulkCopyType = assembly.GetType($"{clientNamespace}.MySqlBulkCopy", true) !;
                    var bulkRowsCopiedEventHandlerType = assembly.GetType($"{clientNamespace}.MySqlRowsCopiedEventHandler", true) !;
                    var bulkCopyColumnMappingType      = assembly.GetType($"{clientNamespace}.MySqlBulkCopyColumnMapping", true) !;
                    var rowsCopiedEventArgsType        = assembly.GetType($"{clientNamespace}.MySqlRowsCopiedEventArgs", true) !;

                    typeMapper.RegisterTypeWrapper <MySqlBulkCopy>(bulkCopyType !);
                    typeMapper.RegisterTypeWrapper <MySqlRowsCopiedEventHandler>(bulkRowsCopiedEventHandlerType);
                    typeMapper.RegisterTypeWrapper <MySqlBulkCopyColumnMapping>(bulkCopyColumnMappingType);
                    typeMapper.RegisterTypeWrapper <MySqlRowsCopiedEventArgs>(rowsCopiedEventArgsType);
                    typeMapper.FinalizeMappings();

                    bulkCopy = new BulkCopyAdapter(
                        typeMapper.BuildWrappedFactory((IDbConnection connection, IDbTransaction? transaction) => new MySqlBulkCopy((MySqlConnection)connection, (MySqlTransaction?)transaction)),
                        typeMapper.BuildWrappedFactory((int source, string destination) => new MySqlBulkCopyColumnMapping(source, destination, null)));
                }
                else
                {
                    typeMapper.FinalizeMappings();
                }

                var typeGetter        = typeMapper.Type <MySqlParameter>().Member(p => p.MySqlDbType).BuildGetter <IDbDataParameter>();
                var dateTimeConverter = typeMapper.MapLambda((MySqlDateTime dt) => dt.GetDateTime());

                var mappingSchema = new MappingSchema();

                mappingSchema.SetDataType(mySqlDateTimeType, DataType.DateTime2);
                mappingSchema.SetConvertExpression(mySqlDateTimeType, typeof(DateTime), dateTimeConverter);

                return(new MySqlProviderAdapter(
                           MySqlProvider.MySqlConnector,
                           connectionType,
                           dataReaderType,
                           parameterType,
                           commandType,
                           transactionType,
                           null,
                           mySqlDateTimeType,
                           mySqlGeometryType,
                           null,
                           p => typeGetter(p),
                           null,
                           "GetDateTimeOffset",
                           "GetMySqlDateTime",
                           typesNamespace,
                           mappingSchema,
                           bulkCopy));
            }
        private static SqlServerProviderAdapter CreateAdapter(string assemblyName, string clientNamespace, string factoryName)
        {
            var isSystem = assemblyName == SystemAssemblyName;

            Assembly?assembly;

#if NET45 || NET46
            if (isSystem)
            {
                assembly = typeof(System.Data.SqlClient.SqlConnection).Assembly;
            }
            else
#endif
            {
                assembly = Common.Tools.TryLoadAssembly(assemblyName, factoryName);
            }

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

            var connectionType                 = assembly.GetType($"{clientNamespace}.SqlConnection", true);
            var parameterType                  = assembly.GetType($"{clientNamespace}.SqlParameter", true);
            var dataReaderType                 = assembly.GetType($"{clientNamespace}.SqlDataReader", true);
            var transactionType                = assembly.GetType($"{clientNamespace}.SqlTransaction", true);
            var commandType                    = assembly.GetType($"{clientNamespace}.SqlCommand", true);
            var sqlCommandBuilderType          = assembly.GetType($"{clientNamespace}.SqlCommandBuilder", true);
            var sqlConnectionStringBuilderType = assembly.GetType($"{clientNamespace}.SqlConnectionStringBuilder", true);
            var sqlExceptionType               = assembly.GetType($"{clientNamespace}.SqlException", true);
            var sqlErrorCollectionType         = assembly.GetType($"{clientNamespace}.SqlErrorCollection", true);
            var sqlErrorType                   = assembly.GetType($"{clientNamespace}.SqlError", true);

            var sqlDataRecordType = connectionType.Assembly.GetType(
                isSystem
                                        ? "Microsoft.SqlServer.Server.SqlDataRecord"
                                        : "Microsoft.Data.SqlClient.Server.SqlDataRecord",
                true);

            var bulkCopyType                        = assembly.GetType($"{clientNamespace}.SqlBulkCopy", true);
            var bulkCopyOptionsType                 = assembly.GetType($"{clientNamespace}.SqlBulkCopyOptions", true);
            var bulkRowsCopiedEventHandlerType      = assembly.GetType($"{clientNamespace}.SqlRowsCopiedEventHandler", true);
            var bulkCopyColumnMappingType           = assembly.GetType($"{clientNamespace}.SqlBulkCopyColumnMapping", true);
            var bulkCopyColumnMappingCollectionType = assembly.GetType($"{clientNamespace}.SqlBulkCopyColumnMappingCollection", true);
            var rowsCopiedEventArgsType             = assembly.GetType($"{clientNamespace}.SqlRowsCopiedEventArgs", true);

            var typeMapper = new TypeMapper();

            typeMapper.RegisterTypeWrapper <SqlConnection>(connectionType);
            typeMapper.RegisterTypeWrapper <SqlParameter>(parameterType);
            typeMapper.RegisterTypeWrapper <SqlTransaction>(transactionType);
            typeMapper.RegisterTypeWrapper <SqlErrorCollection>(sqlErrorCollectionType);
            typeMapper.RegisterTypeWrapper <SqlException>(sqlExceptionType);
            typeMapper.RegisterTypeWrapper <SqlError>(sqlErrorType);
            typeMapper.RegisterTypeWrapper <SqlConnectionStringBuilder>(sqlConnectionStringBuilderType);

            // bulk copy types
            typeMapper.RegisterTypeWrapper <SqlBulkCopy>(bulkCopyType);
            typeMapper.RegisterTypeWrapper <SqlBulkCopyOptions>(bulkCopyOptionsType);
            typeMapper.RegisterTypeWrapper <SqlRowsCopiedEventHandler>(bulkRowsCopiedEventHandlerType);
            typeMapper.RegisterTypeWrapper <SqlBulkCopyColumnMapping>(bulkCopyColumnMappingType);
            typeMapper.RegisterTypeWrapper <SqlBulkCopyColumnMappingCollection>(bulkCopyColumnMappingCollectionType);
            typeMapper.RegisterTypeWrapper <SqlRowsCopiedEventArgs>(rowsCopiedEventArgsType);
            typeMapper.FinalizeMappings();

            var paramMapper        = typeMapper.Type <SqlParameter>();
            var dbTypeBuilder      = paramMapper.Member(p => p.SqlDbType);
            var udtTypeNameBuilder = paramMapper.Member(p => p.UdtTypeName);
            var typeNameBuilder    = paramMapper.Member(p => p.TypeName);

            SqlServerTransientExceptionDetector.RegisterExceptionType(sqlExceptionType, exceptionErrorsGettter);

            return(new SqlServerProviderAdapter(
                       connectionType,
                       dataReaderType,
                       parameterType,
                       commandType,
                       transactionType,
                       sqlDataRecordType,
                       sqlExceptionType,

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

                       typeMapper.BuildWrappedFactory((string connectionString) => new SqlConnectionStringBuilder(connectionString)),
                       typeMapper.BuildWrappedFactory((string connectionString) => new SqlConnection(connectionString)),

                       typeMapper.BuildWrappedFactory((IDbConnection connection, SqlBulkCopyOptions options, IDbTransaction? transaction) => new SqlBulkCopy((SqlConnection)connection, options, (SqlTransaction?)transaction)),
                       typeMapper.BuildWrappedFactory((int source, string destination) => new SqlBulkCopyColumnMapping(source, destination))));

            IEnumerable <int> exceptionErrorsGettter(Exception ex) => typeMapper.Wrap <SqlException>(ex).Errors.Errors.Select(err => err.Number);
        }
Exemple #8
0
        private static SybaseProviderAdapter CreateAdapter(string assemblyName, string clientNamespace, string?dbFactoryName, bool supportsBulkCopy)
        {
            var assembly = Common.Tools.TryLoadAssembly(assemblyName, dbFactoryName);

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

            var connectionType  = assembly.GetType($"{clientNamespace}.AseConnection", true);
            var commandType     = assembly.GetType($"{clientNamespace}.AseCommand", true);
            var parameterType   = assembly.GetType($"{clientNamespace}.AseParameter", true);
            var dataReaderType  = assembly.GetType($"{clientNamespace}.AseDataReader", true);
            var transactionType = assembly.GetType($"{clientNamespace}.AseTransaction", true);
            var dbType          = assembly.GetType($"{clientNamespace}.AseDbType", true);

            var typeMapper = new TypeMapper();

            typeMapper.RegisterTypeWrapper <AseConnection>(connectionType);
            typeMapper.RegisterTypeWrapper <AseParameter>(parameterType);
            typeMapper.RegisterTypeWrapper <AseDbType>(dbType);
            typeMapper.RegisterTypeWrapper <AseTransaction>(transactionType);

            BulkCopyAdapter?bulkCopy = null;

            if (supportsBulkCopy)
            {
                var bulkCopyType                        = assembly.GetType($"{clientNamespace}.AseBulkCopy", true);
                var bulkCopyOptionsType                 = assembly.GetType($"{clientNamespace}.AseBulkCopyOptions", true);
                var bulkRowsCopiedEventHandlerType      = assembly.GetType($"{clientNamespace}.AseRowsCopiedEventHandler", true);
                var bulkCopyColumnMappingType           = assembly.GetType($"{clientNamespace}.AseBulkCopyColumnMapping", true);
                var bulkCopyColumnMappingCollectionType = assembly.GetType($"{clientNamespace}.AseBulkCopyColumnMappingCollection", true);
                var rowsCopiedEventArgsType             = assembly.GetType($"{clientNamespace}.AseRowsCopiedEventArgs", true);

                typeMapper.RegisterTypeWrapper <AseBulkCopy>(bulkCopyType);
                typeMapper.RegisterTypeWrapper <AseBulkCopyOptions>(bulkCopyOptionsType);
                typeMapper.RegisterTypeWrapper <AseRowsCopiedEventHandler>(bulkRowsCopiedEventHandlerType);
                typeMapper.RegisterTypeWrapper <AseBulkCopyColumnMapping>(bulkCopyColumnMappingType);
                typeMapper.RegisterTypeWrapper <AseBulkCopyColumnMappingCollection>(bulkCopyColumnMappingCollectionType);
                typeMapper.RegisterTypeWrapper <AseRowsCopiedEventArgs>(rowsCopiedEventArgsType);
                typeMapper.FinalizeMappings();

                bulkCopy = new BulkCopyAdapter(
                    typeMapper.BuildWrappedFactory((IDbConnection connection, AseBulkCopyOptions options, IDbTransaction? transaction) => new AseBulkCopy((AseConnection)connection, options, (AseTransaction?)transaction)),
                    typeMapper.BuildWrappedFactory((string source, string destination) => new AseBulkCopyColumnMapping(source, destination)));
            }
            else
            {
                typeMapper.FinalizeMappings();
            }

            var paramMapper   = typeMapper.Type <AseParameter>();
            var dbTypeBuilder = paramMapper.Member(p => p.AseDbType);

            return(new SybaseProviderAdapter(
                       connectionType,
                       dataReaderType,
                       parameterType,
                       commandType,
                       transactionType,
                       dbTypeBuilder.BuildSetter <IDbDataParameter>(),
                       dbTypeBuilder.BuildGetter <IDbDataParameter>(),
                       bulkCopy));
        }
Exemple #9
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);
            }
        }
        DB2ProviderAdapter()
        {
            var clientNamespace = ClientNamespace;
            var assembly        = Tools.TryLoadAssembly(AssemblyName, ProviderFactoryName);

            if (assembly == null && AssemblyNameOld != null)
            {
                assembly = Tools.TryLoadAssembly(AssemblyNameOld, ProviderFactoryName);
                if (assembly != null)
                {
                    clientNamespace = ClientNamespaceOld !;
                }
            }
            else if (AssemblyNameOld != null && assembly.GetName().Name == AssemblyNameOld)
            {
                // cover case when provider factory loaded old assembly
                clientNamespace = ClientNamespaceOld !;
            }

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

            ConnectionType  = assembly.GetType($"{clientNamespace}.DB2Connection", true) !;
            ParameterType   = assembly.GetType($"{clientNamespace}.DB2Parameter", true) !;
            DataReaderType  = assembly.GetType($"{clientNamespace}.DB2DataReader", true) !;
            TransactionType = assembly.GetType($"{clientNamespace}.DB2Transaction", true) !;
            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) !;

            MappingSchema = new DB2AdapterMappingSchema();

            DB2BinaryType       = LoadType("DB2Binary", DataType.VarBinary) !;
            DB2BlobType         = LoadType("DB2Blob", DataType.Blob) !;
            DB2ClobType         = LoadType("DB2Clob", DataType.NText) !;
            DB2DateType         = LoadType("DB2Date", DataType.Date) !;
            DB2DateTimeType     = LoadType("DB2DateTime", DataType.DateTime, true);
            DB2DecimalType      = LoadType("DB2Decimal", DataType.Decimal) !;
            DB2DecimalFloatType = LoadType("DB2DecimalFloat", DataType.Decimal) !;
            DB2DoubleType       = LoadType("DB2Double", DataType.Double) !;
            DB2Int16Type        = LoadType("DB2Int16", DataType.Int16) !;
            DB2Int32Type        = LoadType("DB2Int32", DataType.Int32) !;
            DB2Int64Type        = LoadType("DB2Int64", DataType.Int64) !;
            DB2RealType         = LoadType("DB2Real", DataType.Single) !;
            DB2Real370Type      = LoadType("DB2Real370", DataType.Single) !;
            DB2RowIdType        = LoadType("DB2RowId", DataType.VarBinary) !;
            DB2StringType       = LoadType("DB2String", DataType.NVarChar) !;
            DB2TimeType         = LoadType("DB2Time", DataType.Time) !;
            DB2TimeStampType    = LoadType("DB2TimeStamp", DataType.DateTime2) !;
            DB2XmlType          = LoadType("DB2Xml", DataType.Xml) !;
            DB2TimeSpanType     = LoadType("DB2TimeSpan", DataType.Timestamp, true, true);
            // not mapped currently: DB2MonthSpan, DB2SmartLOB, DB2TimeStampOffset, DB2XsrObjectId

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

            IsDB2BinaryNull = db2BinaryBuilder.BuildGetter <object>();

            var dbTypeBuilder = typeMapper.Type <DB2Parameter>().Member(p => p.DB2Type);

            SetDbType = dbTypeBuilder.BuildSetter <DbParameter>();
            GetDbType = dbTypeBuilder.BuildGetter <DbParameter>();


            BulkCopy = new BulkCopyAdapter(
                typeMapper.BuildWrappedFactory((DbConnection connection, DB2BulkCopyOptions options) => new DB2BulkCopy((DB2Connection)(object)connection, options)),
                typeMapper.BuildWrappedFactory((int source, string destination) => new DB2BulkCopyColumnMapping(source, destination)));

            CreateConnection = typeMapper.BuildWrappedFactory((string connectionString) => new DB2Connection(connectionString));

            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);
            }
        }
Exemple #11
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);
        }