Example #1
0
            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));
            }
Example #2
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);
            }
        }
Example #3
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));
        }
Example #4
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);
            }
        }
Example #5
0
        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);
            }
        }
Example #6
0
        private DB2ProviderAdapter(
            Type connectionType,
            Type dataReaderType,
            Type parameterType,
            Type commandType,
            Type transactionType,

            Type?db2DateTimeType,
            Type db2BinaryType,
            Type db2BlobType,
            Type db2ClobType,
            Type db2DateType,
            Type db2DecimalType,
            Type db2DecimalFloatType,
            Type db2DoubleType,
            Type db2Int16Type,
            Type db2Int32Type,
            Type db2Int64Type,
            Type db2RealType,
            Type db2Real370Type,
            Type db2RowIdType,
            Type db2StringType,
            Type db2TimeType,
            Type db2TimeStampType,
            Type db2XmlType,
            // optional, because recent provider version contains it as obsolete stub
            Type?db2TimeSpanType,

            MappingSchema mappingSchema,

            Action <IDbDataParameter, DB2Type> dbTypeSetter,
            Func <IDbDataParameter, DB2Type> dbTypeGetter,

            Func <string, DB2Connection> connectionCreator,
            Func <object, bool> isDB2BinaryNull,

            BulkCopyAdapter bulkCopy)
        {
            ConnectionType  = connectionType;
            DataReaderType  = dataReaderType;
            ParameterType   = parameterType;
            CommandType     = commandType;
            TransactionType = transactionType;

            DB2DateTimeType     = db2DateTimeType;
            DB2BinaryType       = db2BinaryType;
            DB2BlobType         = db2BlobType;
            DB2ClobType         = db2ClobType;
            DB2DateType         = db2DateType;
            DB2DecimalType      = db2DecimalType;
            DB2DecimalFloatType = db2DecimalFloatType;
            DB2DoubleType       = db2DoubleType;
            DB2Int16Type        = db2Int16Type;
            DB2Int32Type        = db2Int32Type;
            DB2Int64Type        = db2Int64Type;
            DB2RealType         = db2RealType;
            DB2Real370Type      = db2Real370Type;
            DB2RowIdType        = db2RowIdType;
            DB2StringType       = db2StringType;
            DB2TimeType         = db2TimeType;
            DB2TimeStampType    = db2TimeStampType;
            DB2XmlType          = db2XmlType;
            DB2TimeSpanType     = db2TimeSpanType;

            MappingSchema = mappingSchema;

            SetDbType = dbTypeSetter;
            GetDbType = dbTypeGetter;

            CreateConnection = connectionCreator;
            IsDB2BinaryNull  = isDB2BinaryNull;

            BulkCopy = bulkCopy;
        }
Example #7
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);
        }