Exemplo n.º 1
0
        public override int BulkCopy <T>(
            [JetBrains.Annotations.NotNull] DataConnection dataConnection, int maxBatchSize, IEnumerable <T> source)
        {
            if (dataConnection == null)
            {
                throw new ArgumentNullException("dataConnection");
            }

            var connection = dataConnection.Connection as SqlConnection;

            if (connection != null)
            {
                var ed = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
                var rd = new BulkCopyReader(ed, source);
                var bc = dataConnection.Transaction == null ?
                         new SqlBulkCopy(connection) :
                         new SqlBulkCopy(connection, SqlBulkCopyOptions.Default, (SqlTransaction)dataConnection.Transaction);

                bc.BatchSize            = maxBatchSize;
                bc.DestinationTableName = ed.TableName;

                for (var i = 0; i < rd.Columns.Length; i++)
                {
                    bc.ColumnMappings.Add(new SqlBulkCopyColumnMapping(i, rd.Columns[i].ColumnName));
                }

                bc.WriteToServer(rd);

                return(rd.Count);
            }

            return(base.BulkCopy(dataConnection, maxBatchSize, source));
        }
Exemplo n.º 2
0
        public override int InsertBatch <T>(
            DbManager db,
            string insertText,
            IEnumerable <T> collection,
            MemberMapper[]                 members,
            int maxBatchSize,
            DbManager.ParameterProvider <T> getParameters)
        {
            var idx = insertText.IndexOf('\n');
            var tbl = insertText.Substring(0, idx).Substring("INSERT INTO ".Length).TrimEnd('\r');
            var rd  = new BulkCopyReader(members, collection);
            var bc  = new SqlBulkCopy((SqlConnection)db.Connection, SqlDataProvider.SqlBulkCopyOptions, (SqlTransaction)db.Transaction)
            {
                BatchSize            = maxBatchSize,
                DestinationTableName = tbl,
            };

            for (var index = 0; index < members.Length; index++)
            {
                bc.ColumnMappings.Add(new SqlBulkCopyColumnMapping(index, members[index].Name));
            }

            bc.WriteToServer(rd);

            return(rd.Count);
        }
Exemplo n.º 3
0
        public override int InsertBatch <T>(
            DbManager db,
            string insertText,
            IEnumerable <T> collection,
            MemberMapper[]                 members,
            int maxBatchSize,
            DbManager.ParameterProvider <T> getParameters)
        {
            if (db.Transaction != null)
            {
                return(base.InsertBatch(db, insertText, collection, members, maxBatchSize, getParameters));
            }

            var idx = insertText.IndexOf('\n');
            var tbl = insertText.Substring(0, idx).Substring("INSERT INTO ".Length).TrimEnd('\r');
            var rd  = new BulkCopyReader(members, collection);
            var bc  = new SqlBulkCopy((SqlConnection)db.Connection)
            {
                BatchSize            = maxBatchSize,
                DestinationTableName = tbl,
            };

            foreach (var memberMapper in members)
            {
                bc.ColumnMappings.Add(new SqlBulkCopyColumnMapping(memberMapper.Ordinal, memberMapper.Name));
            }

            bc.WriteToServer(rd);

            return(rd.Count);
        }
Exemplo n.º 4
0
        public override int BulkCopy <T>(
            [JetBrains.Annotations.NotNull] DataConnection dataConnection,
            BulkCopyOptions options,
            IEnumerable <T> source)
        {
            if (dataConnection == null)
            {
                throw new ArgumentNullException("dataConnection");
            }

            var connection = dataConnection.Connection as SqlConnection;

            if (connection != null)
            {
                var ed      = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
                var columns = ed.Columns.Where(c => !c.SkipOnInsert).ToList();
                var sb      = CreateSqlBuilder();
                var rd      = new BulkCopyReader(this, columns, source);
                var sqlopt  = SqlBulkCopyOptions.Default;

                if (options.CheckConstraints.HasValue)
                {
                    sqlopt |= SqlBulkCopyOptions.CheckConstraints;
                }

                using (var bc = dataConnection.Transaction == null ?
                                new SqlBulkCopy(connection) :
                                new SqlBulkCopy(connection, sqlopt, (SqlTransaction)dataConnection.Transaction))
                {
                    if (options.MaxBatchSize.HasValue)
                    {
                        bc.BatchSize = options.MaxBatchSize.Value;
                    }
                    if (options.MaxBatchSize.HasValue)
                    {
                        bc.BatchSize = options.MaxBatchSize.Value;
                    }
                    if (options.BulkCopyTimeout.HasValue)
                    {
                        bc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                    }

                    bc.DestinationTableName = sb.Convert(ed.TableName, ConvertType.NameToQueryTable).ToString();

                    for (var i = 0; i < columns.Count; i++)
                    {
                        bc.ColumnMappings.Add(new SqlBulkCopyColumnMapping(
                                                  i,
                                                  sb.Convert(columns[i].ColumnName, ConvertType.NameToQueryField).ToString()));
                    }

                    bc.WriteToServer(rd);

                    return(rd.Count);
                }
            }

            return(base.BulkCopy(dataConnection, options, source));
        }
Exemplo n.º 5
0
        public override int InsertBatch <T>(
            DbManager db,
            string insertText,
            IEnumerable <T> collection,
            MemberMapper[]                 members,
            int maxBatchSize,
            DbManager.ParameterProvider <T> getParameters)
        {
            //return base.InsertBatch(db, insertText, collection, members, maxBatchSize, getParameters);

            var idx = insertText.IndexOf('\n');
            var tbl = insertText.Substring(0, idx).Substring("INSERT INTO ".Length).TrimEnd('\r');
            var rd  = new BulkCopyReader(members, collection);
            var bc  = new SqlBulkCopy((SqlConnection)db.Connection)
            {
                BatchSize            = maxBatchSize,
                DestinationTableName = tbl,
            };

            bc.WriteToServer(rd);

            return(rd.Count);
        }
Exemplo n.º 6
0
        protected override BulkCopyRowsCopied ProviderSpecificCopy <T>(
            ITable <T> table,
            BulkCopyOptions options,
            IEnumerable <T> source)
        {
            if (table.DataContext is DataConnection dataConnection && _provider.Adapter.BulkCopy != null)
            {
                var connection = _provider.TryGetProviderConnection(dataConnection.Connection, dataConnection.MappingSchema);

                // for run in transaction see
                // https://stackoverflow.com/questions/57675379
                // provider will call sp_oledb_columns which creates temp table
                var transaction = dataConnection.Transaction;
                if (connection != null && transaction != null)
                {
                    transaction = _provider.TryGetProviderTransaction(transaction, dataConnection.MappingSchema);
                }

                if (connection != null && (dataConnection.Transaction == null || transaction != null))
                {
                    var ed      = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
                    var columns = ed.Columns.Where(c => !c.SkipOnInsert || options.KeepIdentity == true && c.IsIdentity).ToList();
                    var sb      = _provider.CreateSqlBuilder(dataConnection.MappingSchema);
                    var rd      = new BulkCopyReader(dataConnection, columns, source);
                    var sqlopt  = SybaseProviderAdapter.AseBulkCopyOptions.Default;
                    var rc      = new BulkCopyRowsCopied();

                    if (options.CheckConstraints == true)
                    {
                        sqlopt |= SybaseProviderAdapter.AseBulkCopyOptions.CheckConstraints;
                    }
                    if (options.KeepIdentity == true)
                    {
                        sqlopt |= SybaseProviderAdapter.AseBulkCopyOptions.KeepIdentity;
                    }
                    if (options.TableLock == true)
                    {
                        sqlopt |= SybaseProviderAdapter.AseBulkCopyOptions.TableLock;
                    }
                    if (options.KeepNulls == true)
                    {
                        sqlopt |= SybaseProviderAdapter.AseBulkCopyOptions.KeepNulls;
                    }
                    if (options.FireTriggers == true)
                    {
                        sqlopt |= SybaseProviderAdapter.AseBulkCopyOptions.FireTriggers;
                    }
                    if (options.UseInternalTransaction == true)
                    {
                        sqlopt |= SybaseProviderAdapter.AseBulkCopyOptions.UseInternalTransaction;
                    }

                    using (var bc = _provider.Adapter.BulkCopy.Create(connection, sqlopt, transaction))
                    {
                        if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                        {
                            bc.NotifyAfter = options.NotifyAfter;

                            bc.AseRowsCopied += (sender, args) =>
                            {
                                rc.RowsCopied = args.RowCopied;
                                options.RowsCopiedCallback(rc);
                                if (rc.Abort)
                                {
                                    args.Abort = true;
                                }
                            };
                        }

                        if (options.MaxBatchSize.HasValue)
                        {
                            bc.BatchSize = options.MaxBatchSize.Value;
                        }
                        if (options.BulkCopyTimeout.HasValue)
                        {
                            bc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                        }

                        var tableName = GetTableName(sb, options, table);

                        // do not convert table and column names to valid sql name, as sybase bulk copy implementation
                        // doesn't understand escaped names (facepalm)
                        // which means it will probably fail when escaping required anyways...
                        bc.DestinationTableName = GetDestinationTableName(sb, options, table);

                        for (var i = 0; i < columns.Count; i++)
                        {
                            bc.ColumnMappings.Add(_provider.Adapter.BulkCopy.CreateColumnMapping(columns[i].ColumnName, columns[i].ColumnName));
                        }

                        TraceAction(
                            dataConnection,
                            () => "INSERT BULK " + tableName + "(" + string.Join(", ", columns.Select(x => x.ColumnName)) + Environment.NewLine,
                            () => { bc.WriteToServer(rd); return(rd.Count); });
                    }

                    if (rc.RowsCopied != rd.Count)
                    {
                        rc.RowsCopied = rd.Count;

                        if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                        {
                            options.RowsCopiedCallback(rc);
                        }
                    }

                    return(rc);
                }
            }

            return(MultipleRowsCopy(table, options, source));
        }
Exemplo n.º 7
0
        public override int BulkCopy <T>(
            [JetBrains.Annotations.NotNull] DataConnection dataConnection,
            BulkCopyOptions options,
            IEnumerable <T> source)
        {
            if (dataConnection == null)
            {
                throw new ArgumentNullException("dataConnection");
            }

            var bkCopyType = options.BulkCopyType == BulkCopyType.Default ?
                             DB2Tools.DefaultBulkCopyType :
                             options.BulkCopyType;

            if (bkCopyType == BulkCopyType.RowByRow)
            {
                return(base.BulkCopy(dataConnection, options, source));
            }

            var sqlBuilder = (BasicSqlBuilder)CreateSqlBuilder();
            var descriptor = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
            var tableName  = sqlBuilder
                             .BuildTableName(
                new StringBuilder(),
                descriptor.DatabaseName == null ? null : sqlBuilder.Convert(descriptor.DatabaseName, ConvertType.NameToDatabase).ToString(),
                descriptor.SchemaName == null ? null : sqlBuilder.Convert(descriptor.SchemaName, ConvertType.NameToOwner).ToString(),
                descriptor.TableName == null ? null : sqlBuilder.Convert(descriptor.TableName, ConvertType.NameToQueryTable).ToString())
                             .ToString();

            if (bkCopyType == BulkCopyType.ProviderSpecific && dataConnection.Transaction == null)
            {
                if (_bulkCopyCreator == null)
                {
                    var connType          = GetConnectionType();
                    var bulkCopyType      = connType.Assembly.GetType("IBM.Data.DB2.DB2BulkCopy", false);
                    var columnMappingType = connType.Assembly.GetType("IBM.Data.DB2.DB2BulkCopyColumnMapping", false);

                    if (bulkCopyType != null)
                    {
                        {
                            var p = Expression.Parameter(typeof(IDbConnection), "p");
                            var l = Expression.Lambda <Func <IDbConnection, IDisposable> >(
                                Expression.Convert(
                                    Expression.New(
                                        bulkCopyType.GetConstructor(new[] { connType }),
                                        Expression.Convert(p, connType)),
                                    typeof(IDisposable)),
                                p);

                            _bulkCopyCreator = l.Compile();
                        }
                        {
                            var p1 = Expression.Parameter(typeof(int), "p1");
                            var p2 = Expression.Parameter(typeof(string), "p2");
                            var l  = Expression.Lambda <Func <int, string, object> >(
                                Expression.Convert(
                                    Expression.New(
                                        columnMappingType.GetConstructor(new[] { typeof(int), typeof(string) }),
                                        new [] { p1, p2 }),
                                    typeof(object)),
                                p1, p2);

                            _columnMappingCreator = l.Compile();
                        }
                    }
                }

                if (_bulkCopyCreator != null)
                {
                    var columns = descriptor.Columns.Where(c => !c.SkipOnInsert).ToList();
                    var rd      = new BulkCopyReader(this, columns, source);

                    using (var bc = _bulkCopyCreator(dataConnection.Connection))
                    {
                        dynamic dbc = bc;

                        if (options.BulkCopyTimeout.HasValue)
                        {
                            dbc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                        }

                        dbc.DestinationTableName = tableName;

                        for (var i = 0; i < columns.Count; i++)
                        {
                            dbc.ColumnMappings.Add((dynamic)_columnMappingCreator(i, columns[i].ColumnName));
                        }

                        dbc.WriteToServer(rd);
                    }

                    return(rd.Count);
                }
            }

            return(MultipleRowsBulkCopy(dataConnection, options, source, sqlBuilder, descriptor, tableName));
        }
Exemplo n.º 8
0
        protected override BulkCopyRowsCopied ProviderSpecificCopy <T>(
            ITable <T> table,
            BulkCopyOptions options,
            IEnumerable <T> source)
        {
            if (table.DataContext is DataConnection dataConnection && dataConnection.Transaction == null && _provider.Adapter.BulkCopy != null)
            {
                var connection = _provider.TryGetProviderConnection(dataConnection.Connection, dataConnection.MappingSchema);

                if (connection != null)
                {
                    var ed        = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
                    var columns   = ed.Columns.Where(c => !c.SkipOnInsert || options.KeepIdentity == true && c.IsIdentity).ToList();
                    var sb        = _provider.CreateSqlBuilder(dataConnection.MappingSchema);
                    var rd        = new BulkCopyReader <T>(dataConnection, columns, source);
                    var sqlopt    = OracleProviderAdapter.OracleBulkCopyOptions.Default;
                    var rc        = new BulkCopyRowsCopied();
                    var tableName = GetTableName(sb, options, table);

                    if (options.UseInternalTransaction == true)
                    {
                        sqlopt |= OracleProviderAdapter.OracleBulkCopyOptions.UseInternalTransaction;
                    }

                    using (var bc = _provider.Adapter.BulkCopy.Create(connection, sqlopt))
                    {
                        var notifyAfter = options.NotifyAfter == 0 && options.MaxBatchSize.HasValue
                                                        ? options.MaxBatchSize.Value
                                                        : options.NotifyAfter;

                        if (notifyAfter != 0 && options.RowsCopiedCallback != null)
                        {
                            bc.NotifyAfter = options.NotifyAfter;

                            bc.OracleRowsCopied += (sender, args) =>
                            {
                                rc.RowsCopied = args.RowsCopied;
                                options.RowsCopiedCallback(rc);
                                if (rc.Abort)
                                {
                                    args.Abort = true;
                                }
                            };
                        }

                        if (options.MaxBatchSize.HasValue)
                        {
                            bc.BatchSize = options.MaxBatchSize.Value;
                        }

                        if (options.BulkCopyTimeout.HasValue)
                        {
                            bc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                        }
                        else if (Configuration.Data.BulkCopyUseConnectionCommandTimeout)
                        {
                            bc.BulkCopyTimeout = connection.ConnectionTimeout;
                        }

                        bc.DestinationTableName = tableName;

                        for (var i = 0; i < columns.Count; i++)
                        {
                            bc.ColumnMappings.Add(_provider.Adapter.BulkCopy.CreateColumnMapping(i, columns[i].ColumnName));
                        }

                        TraceAction(
                            dataConnection,
                            () => "INSERT BULK " + tableName + "(" + string.Join(", ", columns.Select(x => x.ColumnName)) + Environment.NewLine,
                            () => { bc.WriteToServer(rd); return(rd.Count); });
                    }

                    if (rc.RowsCopied != rd.Count)
                    {
                        rc.RowsCopied = rd.Count;

                        if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                        {
                            options.RowsCopiedCallback(rc);
                        }
                    }

                    return(rc);
                }
            }


            return(MultipleRowsCopy(table, options, source));
        }
Exemplo n.º 9
0
        protected override BulkCopyRowsCopied ProviderSpecificCopy <T>(
            [JetBrains.Annotations.NotNull] DataConnection dataConnection,
            BulkCopyOptions options,
            IEnumerable <T> source)
        {
            if (dataConnection == null)
            {
                throw new ArgumentNullException("dataConnection");
            }

            var connection = dataConnection.Connection;

            if (connection == null)
            {
                return(MultipleRowsCopy(dataConnection, options, source));
            }

            if (!(connection.GetType() == _connectionType || connection.GetType().IsSubclassOfEx(_connectionType)))
            {
                return(MultipleRowsCopy(dataConnection, options, source));
            }

            var transaction = dataConnection.Transaction;
            var ed          = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
            var columns     = ed.Columns.Where(c => !c.SkipOnInsert || options.KeepIdentity == true && c.IsIdentity).ToList();
            var rc          = new BulkCopyRowsCopied();

            if (_bulkCopyCreator == null)
            {
                var clientNamespace = _dataProvider.ConnectionNamespace;
                var bulkCopyType    = _connectionType.AssemblyEx().GetType(clientNamespace + ".HanaBulkCopy", false);
                _bulkCopyOptionType = _connectionType.AssemblyEx().GetType(clientNamespace + ".HanaBulkCopyOptions", false);
                var columnMappingType = _connectionType.AssemblyEx().GetType(clientNamespace + ".HanaBulkCopyColumnMapping", false);
                var transactionType   = _connectionType.AssemblyEx().GetType(clientNamespace + ".HanaTransaction", false);

                if (bulkCopyType != null)
                {
                    _bulkCopyCreator      = SapHanaCreateBulkCopyCreator(_connectionType, bulkCopyType, _bulkCopyOptionType, transactionType);
                    _columnMappingCreator = CreateColumnMappingCreator(columnMappingType);
                }
            }

            if (_bulkCopyCreator == null)
            {
                return(MultipleRowsCopy(dataConnection, options, source));
            }

            int hanaOptions = 0;             //default;

            if (options.KeepIdentity == true)
            {
                // instead of adding new option in HANA 2 provider to a free bit to preserve compatibility,
                // SAP reused value, assigned to TableLock before
                if (Enum.GetNames(_bulkCopyOptionType).Any(_ => _ == KeepIdentityOptionName))
                {
                    hanaOptions = hanaOptions | (int)Enum.Parse(_bulkCopyOptionType, KeepIdentityOptionName);
                }
                else
                {
                    throw new LinqToDBException($"{nameof(BulkCopyOptions)}.{nameof(BulkCopyOptions.KeepIdentity)} = true is not supported by your SAP HANA provider version");
                }
            }

            using (var bc = _bulkCopyCreator(connection, hanaOptions, transaction))
            {
                dynamic dbc = bc;

                if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                {
                    if (_bulkCopySubscriber == null)
                    {
                        _bulkCopySubscriber = CreateBulkCopySubscriber(bc, "HannaRowsCopied");
                    }

                    dbc.NotifyAfter = options.NotifyAfter;

                    _bulkCopySubscriber(bc, arg =>
                    {
                        dynamic darg  = arg;
                        rc.RowsCopied = darg.RowsCopied;
                        options.RowsCopiedCallback(rc);
                        if (rc.Abort)
                        {
                            darg.Abort = true;
                        }
                    });
                }

                if (options.MaxBatchSize.HasValue)
                {
                    dbc.BatchSize = options.MaxBatchSize.Value;
                }
                if (options.BulkCopyTimeout.HasValue)
                {
                    dbc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                }

                var sqlBuilder = _dataProvider.CreateSqlBuilder();
                var descriptor = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
                var tableName  = GetTableName(sqlBuilder, options, descriptor);

                dbc.DestinationTableName = tableName;

                for (var i = 0; i < columns.Count; i++)
                {
                    dbc.ColumnMappings.Add((dynamic)_columnMappingCreator(i, columns[i].ColumnName));
                }

                var rd = new BulkCopyReader(_dataProvider, dataConnection.MappingSchema, columns, source);

                TraceAction(
                    dataConnection,
                    "INSERT BULK " + tableName + Environment.NewLine,
                    () => { dbc.WriteToServer(rd); return(rd.Count); });

                if (rc.RowsCopied != rd.Count)
                {
                    rc.RowsCopied = rd.Count;

                    if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                    {
                        options.RowsCopiedCallback(rc);
                    }
                }

                return(rc);
            }
        }
Exemplo n.º 10
0
        protected override BulkCopyRowsCopied ProviderSpecificCopy <T>(
            ITable <T> table,
            BulkCopyOptions options,
            IEnumerable <T> source)
        {
            if (table.DataContext is DataConnection dataConnection)
            {
                var connection = _provider.TryGetProviderConnection(dataConnection.Connection, dataConnection.MappingSchema);

                var transaction = dataConnection.Transaction;
                if (connection != null && transaction != null)
                {
                    transaction = _provider.TryGetProviderTransaction(transaction, dataConnection.MappingSchema);
                }

                if (connection != null && (dataConnection.Transaction == null || transaction != null))
                {
                    var ed      = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
                    var columns = ed.Columns.Where(c => !c.SkipOnInsert || options.KeepIdentity == true && c.IsIdentity).ToList();
                    var sb      = _provider.CreateSqlBuilder(dataConnection.MappingSchema);
                    var rd      = new BulkCopyReader(dataConnection, columns, source);
                    var sqlopt  = SqlServerProviderAdapter.SqlBulkCopyOptions.Default;
                    var rc      = new BulkCopyRowsCopied();

                    if (options.CheckConstraints == true)
                    {
                        sqlopt |= SqlServerProviderAdapter.SqlBulkCopyOptions.CheckConstraints;
                    }
                    if (options.KeepIdentity == true)
                    {
                        sqlopt |= SqlServerProviderAdapter.SqlBulkCopyOptions.KeepIdentity;
                    }
                    if (options.TableLock == true)
                    {
                        sqlopt |= SqlServerProviderAdapter.SqlBulkCopyOptions.TableLock;
                    }
                    if (options.KeepNulls == true)
                    {
                        sqlopt |= SqlServerProviderAdapter.SqlBulkCopyOptions.KeepNulls;
                    }
                    if (options.FireTriggers == true)
                    {
                        sqlopt |= SqlServerProviderAdapter.SqlBulkCopyOptions.FireTriggers;
                    }
                    if (options.UseInternalTransaction == true)
                    {
                        sqlopt |= SqlServerProviderAdapter.SqlBulkCopyOptions.UseInternalTransaction;
                    }

                    using (var bc = _provider.Adapter.CreateBulkCopy(connection, sqlopt, transaction))
                    {
                        if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                        {
                            bc.NotifyAfter = options.NotifyAfter;

                            bc.SqlRowsCopied += (sender, args) =>
                            {
                                rc.RowsCopied = args.RowsCopied;
                                options.RowsCopiedCallback(rc);
                                if (rc.Abort)
                                {
                                    args.Abort = true;
                                }
                            };
                        }

                        if (options.MaxBatchSize.HasValue)
                        {
                            bc.BatchSize = options.MaxBatchSize.Value;
                        }
                        if (options.BulkCopyTimeout.HasValue)
                        {
                            bc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                        }

                        var tableName = GetTableName(sb, options, table);

                        bc.DestinationTableName = tableName;

                        for (var i = 0; i < columns.Count; i++)
                        {
                            bc.ColumnMappings.Add(_provider.Adapter.CreateBulkCopyColumnMapping(i, sb.ConvertInline(columns[i].ColumnName, ConvertType.NameToQueryField)));
                        }

                        TraceAction(
                            dataConnection,
                            () => "INSERT BULK " + tableName + "(" + string.Join(", ", columns.Select(x => x.ColumnName)) + Environment.NewLine,
                            () => { bc.WriteToServer(rd); return(rd.Count); });
                    }

                    if (rc.RowsCopied != rd.Count)
                    {
                        rc.RowsCopied = rd.Count;

                        if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                        {
                            options.RowsCopiedCallback(rc);
                        }
                    }

                    return(rc);
                }
            }

            return(MultipleRowsCopy(table, options, source));
        }
Exemplo n.º 11
0
        protected override BulkCopyRowsCopied ProviderSpecificCopy <T>(
            [JetBrains.Annotations.NotNull] ITable <T> table,
            BulkCopyOptions options,
            IEnumerable <T> source)
        {
            if (!(table?.DataContext is DataConnection dataConnection))
            {
                throw new ArgumentNullException(nameof(dataConnection));
            }

            if (dataConnection.Connection is DbConnection dbConnection)
            {
                if (Proxy.GetUnderlyingObject(dbConnection) is SqlConnection connection)
                {
                    var ed      = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
                    var columns = ed.Columns.Where(c => !c.SkipOnInsert || options.KeepIdentity == true && c.IsIdentity).ToList();
                    var sb      = _dataProvider.CreateSqlBuilder();
                    var rd      = new BulkCopyReader(_dataProvider, dataConnection.MappingSchema, columns, source);
                    var sqlopt  = SqlBulkCopyOptions.Default;
                    var rc      = new BulkCopyRowsCopied();

                    if (options.CheckConstraints == true)
                    {
                        sqlopt |= SqlBulkCopyOptions.CheckConstraints;
                    }
                    if (options.KeepIdentity == true)
                    {
                        sqlopt |= SqlBulkCopyOptions.KeepIdentity;
                    }
                    if (options.TableLock == true)
                    {
                        sqlopt |= SqlBulkCopyOptions.TableLock;
                    }
                    if (options.KeepNulls == true)
                    {
                        sqlopt |= SqlBulkCopyOptions.KeepNulls;
                    }
                    if (options.FireTriggers == true)
                    {
                        sqlopt |= SqlBulkCopyOptions.FireTriggers;
                    }
                    if (options.UseInternalTransaction == true)
                    {
                        sqlopt |= SqlBulkCopyOptions.UseInternalTransaction;
                    }

                    using (var bc = new SqlBulkCopy(connection, sqlopt, (SqlTransaction)dataConnection.Transaction))
                    {
                        if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                        {
                            bc.NotifyAfter = options.NotifyAfter;

                            bc.SqlRowsCopied += (sender, e) =>
                            {
                                rc.RowsCopied = e.RowsCopied;
                                options.RowsCopiedCallback(rc);
                                if (rc.Abort)
                                {
                                    e.Abort = true;
                                }
                            };
                        }

                        if (options.MaxBatchSize.HasValue)
                        {
                            bc.BatchSize = options.MaxBatchSize.Value;
                        }
                        if (options.BulkCopyTimeout.HasValue)
                        {
                            bc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                        }

                        var sqlBuilder = _dataProvider.CreateSqlBuilder();
                        var tableName  = GetTableName(sqlBuilder, options, table);

                        bc.DestinationTableName = tableName;

                        for (var i = 0; i < columns.Count; i++)
                        {
                            bc.ColumnMappings.Add(new SqlBulkCopyColumnMapping(
                                                      i,
                                                      sb.Convert(columns[i].ColumnName, ConvertType.NameToQueryField).ToString()));
                        }

                        TraceAction(
                            dataConnection,
                            () => "INSERT BULK " + tableName + "(" + string.Join(", ", bc.ColumnMappings.Cast <SqlBulkCopyColumnMapping>().Select(x => x.DestinationColumn)) + Environment.NewLine,
                            () => { bc.WriteToServer(rd); return(rd.Count); });
                    }

                    if (rc.RowsCopied != rd.Count)
                    {
                        rc.RowsCopied = rd.Count;

                        if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                        {
                            options.RowsCopiedCallback(rc);
                        }
                    }

                    return(rc);
                }
            }

            return(MultipleRowsCopy(table, options, source));
        }
Exemplo n.º 12
0
        protected override BulkCopyRowsCopied ProviderSpecificCopy <T>(
            ITable <T> table,
            BulkCopyOptions options,
            IEnumerable <T> source)
        {
            if (!(table?.DataContext is DataConnection dataConnection))
            {
                throw new ArgumentNullException(nameof(dataConnection));
            }

            var connection = _provider.TryGetProviderConnection(dataConnection.Connection, dataConnection.MappingSchema);

            var transaction = dataConnection.Transaction;

            if (connection != null && transaction != null)
            {
                transaction = _provider.TryGetProviderTransaction(transaction, dataConnection.MappingSchema);
            }

            if (connection != null && (dataConnection.Transaction == null || transaction != null))
            {
                var ed      = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
                var columns = ed.Columns.Where(c => !c.SkipOnInsert || options.KeepIdentity == true && c.IsIdentity).ToList();
                var rc      = new BulkCopyRowsCopied();


                var hanaOptions = SapHanaProviderAdapter.HanaBulkCopyOptions.Default;

                if (options.KeepIdentity == true)
                {
                    hanaOptions |= SapHanaProviderAdapter.HanaBulkCopyOptions.KeepIdentity;
                }


                using (var bc = _provider.Adapter.CreateBulkCopy(connection, hanaOptions, transaction))
                {
                    if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                    {
                        bc.NotifyAfter = options.NotifyAfter;

                        bc.HanaRowsCopied += (sender, args) =>
                        {
                            rc.RowsCopied = args.RowsCopied;
                            options.RowsCopiedCallback(rc);
                            if (rc.Abort)
                            {
                                args.Abort = true;
                            }
                        };
                    }

                    if (options.MaxBatchSize.HasValue)
                    {
                        bc.BatchSize = options.MaxBatchSize.Value;
                    }
                    if (options.BulkCopyTimeout.HasValue)
                    {
                        bc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                    }

                    var sqlBuilder = dataConnection.DataProvider.CreateSqlBuilder(dataConnection.MappingSchema);
                    var tableName  = GetTableName(sqlBuilder, options, table);

                    bc.DestinationTableName = tableName;

                    for (var i = 0; i < columns.Count; i++)
                    {
                        bc.ColumnMappings.Add(_provider.Adapter.CreateBulkCopyColumnMapping(i, columns[i].ColumnName));
                    }

                    var rd = new BulkCopyReader(dataConnection, columns, source);

                    TraceAction(
                        dataConnection,
                        () => "INSERT BULK " + tableName + Environment.NewLine,
                        () => { bc.WriteToServer(rd); return(rd.Count); });

                    if (rc.RowsCopied != rd.Count)
                    {
                        rc.RowsCopied = rd.Count;

                        if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                        {
                            options.RowsCopiedCallback(rc);
                        }
                    }

                    return(rc);
                }
            }

            return(MultipleRowsCopy(table, options, source));
        }
Exemplo n.º 13
0
        private async Task <BulkCopyRowsCopied> ProviderSpecificCopyInternal <T>(
            ProviderConnections providerConnections,
            ITable <T> table,
            BulkCopyOptions options,
            IAsyncEnumerable <T> source,
            CancellationToken cancellationToken)
        {
            var dataConnection = providerConnections.DataConnection;
            var connection     = providerConnections.ProviderConnection;
            var transaction    = providerConnections.ProviderTransaction;
            var ed             = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
            var columns        = ed.Columns.Where(c => !c.SkipOnInsert || options.KeepIdentity == true && c.IsIdentity).ToList();
            var sb             = _provider.CreateSqlBuilder(dataConnection.MappingSchema);
            var rc             = new BulkCopyRowsCopied();

            var bc = _provider.Adapter.BulkCopy !.Create(connection, transaction);

            if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
            {
                bc.NotifyAfter = options.NotifyAfter;

                bc.MySqlRowsCopied += (sender, args) =>
                {
                    rc.RowsCopied += args.RowsCopied;
                    options.RowsCopiedCallback(rc);
                    if (rc.Abort)
                    {
                        args.Abort = true;
                    }
                };
            }

            if (options.BulkCopyTimeout.HasValue)
            {
                bc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
            }

            var tableName = GetTableName(sb, options, table);

            bc.DestinationTableName = GetTableName(sb, options, table);

            for (var i = 0; i < columns.Count; i++)
            {
                bc.AddColumnMapping(_provider.Adapter.BulkCopy.CreateColumnMapping(i, columns[i].ColumnName));
            }

            // emulate missing BatchSize property
            // this is needed, because MySql fails on big batches, so users should be able to limit batch size
            var batches = EnumerableHelper.Batch(source, options.MaxBatchSize ?? int.MaxValue);

            await foreach (var batch in batches.WithCancellation(cancellationToken).ConfigureAwait(Common.Configuration.ContinueOnCapturedContext))
            {
                var rd = new BulkCopyReader <T>(dataConnection, columns, batch, cancellationToken);

                await TraceActionAsync(
                    dataConnection,
                    () => "INSERT BULK " + tableName + "(" + string.Join(", ", columns.Select(x => x.ColumnName)) + Environment.NewLine,
                    async() => {
                    if (bc.CanWriteToServerAsync2)
                    {
                        await bc.WriteToServerAsync2(rd, cancellationToken).ConfigureAwait(Common.Configuration.ContinueOnCapturedContext);
                    }
                    else
                    if (bc.CanWriteToServerAsync)
                    {
                        await bc.WriteToServerAsync(rd, cancellationToken).ConfigureAwait(Common.Configuration.ContinueOnCapturedContext);
                    }
                    else
                    {
                        bc.WriteToServer(rd);
                    }
                    return(rd.Count);
                }).ConfigureAwait(Common.Configuration.ContinueOnCapturedContext);

                rc.RowsCopied += rd.Count;
            }

            if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
            {
                options.RowsCopiedCallback(rc);
            }

            return(rc);
        }
Exemplo n.º 14
0
        protected BulkCopyRowsCopied IDSProviderSpecificCopy <T>(
            ITable <T> table,
            BulkCopyOptions options,
            IEnumerable <T> source,
            DataConnection dataConnection,
            IDbConnection connection,
            InformixProviderAdapter.BulkCopyAdapter bulkCopy)
        {
            var ed      = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
            var columns = ed.Columns.Where(c => !c.SkipOnInsert || options.KeepIdentity == true && c.IsIdentity).ToList();
            var sb      = _provider.CreateSqlBuilder(dataConnection.MappingSchema);
            var rd      = new BulkCopyReader(dataConnection, columns, source);
            var sqlopt  = InformixProviderAdapter.IfxBulkCopyOptions.Default;
            var rc      = new BulkCopyRowsCopied();

            if (options.KeepIdentity == true)
            {
                sqlopt |= InformixProviderAdapter.IfxBulkCopyOptions.KeepIdentity;
            }
            if (options.TableLock == true)
            {
                sqlopt |= InformixProviderAdapter.IfxBulkCopyOptions.TableLock;
            }

            using (var bc = bulkCopy.Create(connection, sqlopt))
            {
                if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                {
                    bc.NotifyAfter = options.NotifyAfter;

                    bc.IfxRowsCopied += (sender, args) =>
                    {
                        rc.RowsCopied = args.RowsCopied;
                        options.RowsCopiedCallback(rc);
                        if (rc.Abort)
                        {
                            args.Abort = true;
                        }
                    };
                }

                if (options.BulkCopyTimeout.HasValue)
                {
                    bc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                }

                var tableName = GetTableName(sb, options, table);

                bc.DestinationTableName = tableName;

                for (var i = 0; i < columns.Count; i++)
                {
                    bc.ColumnMappings.Add(bulkCopy.CreateColumnMapping(i, sb.Convert(columns[i].ColumnName, ConvertType.NameToQueryField)));
                }

                TraceAction(
                    dataConnection,
                    () => "INSERT BULK " + tableName + "(" + string.Join(", ", columns.Select(x => x.ColumnName)) + Environment.NewLine,
                    () => { bc.WriteToServer(rd); return(rd.Count); });
            }

            if (rc.RowsCopied != rd.Count)
            {
                rc.RowsCopied = rd.Count;

                if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                {
                    options.RowsCopiedCallback(rc);
                }
            }

            return(rc);
        }
Exemplo n.º 15
0
        protected override BulkCopyRowsCopied ProviderSpecificCopy <T>(
            [JetBrains.Annotations.NotNull] ITable <T> table,
            BulkCopyOptions options,
            IEnumerable <T> source)
        {
            if (!(table?.DataContext is DataConnection dataConnection))
            {
                throw new ArgumentNullException(nameof(dataConnection));
            }

            if (dataConnection.Transaction == null)
            {
                var sqlBuilder = dataConnection.DataProvider.CreateSqlBuilder(dataConnection.MappingSchema);
                var descriptor = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
                var tableName  = GetTableName(sqlBuilder, options, table);

                if (_bulkCopyCreator == null)
                {
                    var bulkCopyType       = _connectionType.AssemblyEx().GetType("IBM.Data.DB2.DB2BulkCopy", false);
                    var bulkCopyOptionType = _connectionType.AssemblyEx().GetType("IBM.Data.DB2.DB2BulkCopyOptions", false);
                    var columnMappingType  = _connectionType.AssemblyEx().GetType("IBM.Data.DB2.DB2BulkCopyColumnMapping", false);

                    if (bulkCopyType != null)
                    {
                        _bulkCopyCreator      = CreateBulkCopyCreator(_connectionType, bulkCopyType, bulkCopyOptionType);
                        _columnMappingCreator = CreateColumnMappingCreator(columnMappingType);
                    }
                }

                if (_bulkCopyCreator != null)
                {
                    var columns = descriptor.Columns.Where(c => !c.SkipOnInsert || options.KeepIdentity == true && c.IsIdentity).ToList();
                    var rd      = new BulkCopyReader(dataConnection.DataProvider, dataConnection.MappingSchema, columns, source);
                    var rc      = new BulkCopyRowsCopied();

                    var bcOptions = 0;                     // Default

                    if (options.KeepIdentity == true)
                    {
                        bcOptions |= 1;                                                   // KeepIdentity = 1, TableLock = 2, Truncate = 4,
                    }
                    if (options.TableLock == true)
                    {
                        bcOptions |= 2;
                    }

                    using (var bc = _bulkCopyCreator(Proxy.GetUnderlyingObject((DbConnection)dataConnection.Connection), bcOptions))
                    {
                        dynamic dbc = bc;

                        var notifyAfter = options.NotifyAfter == 0 && options.MaxBatchSize.HasValue ?
                                          options.MaxBatchSize.Value : options.NotifyAfter;

                        if (notifyAfter != 0 && options.RowsCopiedCallback != null)
                        {
                            if (_bulkCopySubscriber == null)
                            {
                                _bulkCopySubscriber = CreateBulkCopySubscriber(bc, "DB2RowsCopied");
                            }

                            dbc.NotifyAfter = notifyAfter;

                            _bulkCopySubscriber(bc, arg =>
                            {
                                dynamic darg  = arg;
                                rc.RowsCopied = darg.RowsCopied;
                                options.RowsCopiedCallback(rc);
                                if (rc.Abort)
                                {
                                    darg.Abort = true;
                                }
                            });
                        }

                        if (options.BulkCopyTimeout.HasValue)
                        {
                            dbc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                        }

                        dbc.DestinationTableName = tableName;

                        for (var i = 0; i < columns.Count; i++)
                        {
                            dbc.ColumnMappings.Add((dynamic)_columnMappingCreator(i, columns[i].ColumnName));
                        }

                        TraceAction(
                            dataConnection,
                            () => "INSERT BULK " + tableName + Environment.NewLine,
                            () => { dbc.WriteToServer(rd); return(rd.Count); });
                    }

                    if (rc.RowsCopied != rd.Count)
                    {
                        rc.RowsCopied = rd.Count;

                        if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                        {
                            options.RowsCopiedCallback(rc);
                        }
                    }

                    return(rc);
                }
            }

            return(MultipleRowsCopy(table, options, source));
        }
Exemplo n.º 16
0
        protected override BulkCopyRowsCopied ProviderSpecificCopy <T>(
            DataConnection dataConnection,
            BulkCopyOptions options,
            IEnumerable <T> source)
        {
            if (dataConnection == null)
            {
                throw new ArgumentNullException("dataConnection");
            }

            var connection = dataConnection.Connection;

            if (connection == null)
            {
                return(MultipleRowsCopy(dataConnection, options, source));
            }

            if (!(connection.GetType() == _connectionType || connection.GetType().IsSubclassOf(_connectionType)))
            {
                return(MultipleRowsCopy(dataConnection, options, source));
            }

            var transaction = dataConnection.Transaction;
            var ed          = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
            var columns     = ed.Columns.Where(c => !c.SkipOnInsert || options.KeepIdentity == true && c.IsIdentity).ToList();
            var rc          = new BulkCopyRowsCopied();

            if (_bulkCopyCreator == null)
            {
                var clientNamespace    = _dataProvider.ConnectionNamespace;
                var bulkCopyType       = _connectionType.Assembly.GetType(clientNamespace + ".HanaBulkCopy", false);
                var bulkCopyOptionType = _connectionType.Assembly.GetType(clientNamespace + ".HanaBulkCopyOptions", false);
                var columnMappingType  = _connectionType.Assembly.GetType(clientNamespace + ".HanaBulkCopyColumnMapping", false);
                var transactionType    = _connectionType.Assembly.GetType(clientNamespace + ".HanaTransaction", false);

                if (bulkCopyType != null)
                {
                    _bulkCopyCreator      = SapHanaCreateBulkCopyCreator(_connectionType, bulkCopyType, bulkCopyOptionType, transactionType);
                    _columnMappingCreator = CreateColumnMappingCreator(columnMappingType);
                }
            }

            if (_bulkCopyCreator == null)
            {
                return(MultipleRowsCopy(dataConnection, options, source));
            }

            const int hanaOptions = 0;             //default;

            using (var bc = _bulkCopyCreator(connection, hanaOptions, transaction))
            {
                dynamic dbc = bc;

                if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                {
                    if (_bulkCopySubscriber == null)
                    {
                        _bulkCopySubscriber = CreateBulkCopySubscriber(bc, "HannaRowsCopied");
                    }

                    dbc.NotifyAfter = options.NotifyAfter;

                    _bulkCopySubscriber(bc, arg =>
                    {
                        dynamic darg  = arg;
                        rc.RowsCopied = darg.RowsCopied;
                        options.RowsCopiedCallback(rc);
                        if (rc.Abort)
                        {
                            darg.Abort = true;
                        }
                    });
                }

                if (options.MaxBatchSize.HasValue)
                {
                    dbc.BatchSize = options.MaxBatchSize.Value;
                }
                if (options.BulkCopyTimeout.HasValue)
                {
                    dbc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                }

                var sqlBuilder = _dataProvider.CreateSqlBuilder();
                var descriptor = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
                var tableName  = GetTableName(sqlBuilder, options, descriptor);

                dbc.DestinationTableName = tableName;

                for (var i = 0; i < columns.Count; i++)
                {
                    dbc.ColumnMappings.Add((dynamic)_columnMappingCreator(i, columns[i].ColumnName));
                }

                var rd = new BulkCopyReader(_dataProvider, columns, source);

                TraceAction(
                    dataConnection,
                    "INSERT BULK " + tableName + Environment.NewLine,
                    () => { dbc.WriteToServer(rd); return(rd.Count); });

                if (rc.RowsCopied != rd.Count)
                {
                    rc.RowsCopied = rd.Count;

                    if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                    {
                        options.RowsCopiedCallback(rc);
                    }
                }

                return(rc);
            }
        }
        private BulkCopyRowsCopied ProviderSpecificCopyImpl_AccessClient <T>(
            ITable <T> table,
            BulkCopyOptions options,
            IEnumerable <T> source,
            DataConnection dataConnection,
            IDbConnection connection,
            DB2iSeriesAccessClientProviderAdapter adapter,
            Action <DataConnection, Func <string>, Func <int> > traceAction)
        {
            var descriptor = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
            var columns    = descriptor.Columns.Where(c => !c.SkipOnInsert || options.KeepIdentity == true && c.IsIdentity).ToList();
            var rd         = new BulkCopyReader <T>(dataConnection, columns, source);
            var rc         = new BulkCopyRowsCopied();
            var sqlBuilder = dataConnection.DataProvider.CreateSqlBuilder(dataConnection.MappingSchema);
            var tableName  = GetTableName(sqlBuilder, options, table);

            var columnNames = columns.Select(x => x.ColumnName);
            var fields      = string.Join(", ", columnNames);
            var parameters  = string.Join(", ", columnNames.Select(x => "@" + x));

            var sql = $"INSERT INTO {tableName} ({fields}) VALUES({parameters})";

            var batchSize = Math.Min(options.MaxBatchSize ?? MAX_ACCESS_CLIENT_BATCH_SIZE, MAX_ACCESS_CLIENT_BATCH_SIZE);
            var sw        = Stopwatch.StartNew();

            using (var cmd = connection.CreateCommand())
            {
                cmd.CommandText = sql;
                adapter.DeriveParameters(cmd);

                var columnDataTypes = cmd.Parameters.Cast <IDbDataParameter>()
                                      .Select(adapter.GetDbType)
                                      .Select(adapter.GetDataType)
                                      .ToList();

                //*LOB and XML types not supported, fallback to multiple rows
                if (columnDataTypes.Any(x => x.In(DataType.Blob, DataType.Text, DataType.NText, DataType.Xml)))
                {
                    return(MultipleRowsCopy(table, options, source));
                }

                var columnDbDataTypes = columns
                                        .Select((x, i) => x
                                                .GetDbDataType(true)
                                                .WithDataType(columnDataTypes[i]))
                                        .ToList();

                var count = 0;
                var notificationBatchCount = 0;
                var bufferEmpty            = false;
                while (rd.Read())
                {
                    var i = 0;
                    bufferEmpty = false;
                    foreach (IDbDataParameter parameter in cmd.Parameters)
                    {
                        dataConnection.DataProvider.SetParameter(
                            dataConnection,
                            parameter,
                            columns[i].ColumnName,
                            columnDbDataTypes[i],
                            rd.GetValue(i++));
                    }

                    try
                    {
                        adapter.AddBatch(cmd);
                    }
                    //In case columns can't be mapped fall back to multiple rows
                    catch
                    {
                        return(MultipleRowsCopy(table, options, source));
                    }

                    count++;
                    notificationBatchCount++;

                    if (count % batchSize == 0)
                    {
                        execute();
                        if (rc.Abort)
                        {
                            return(rc);
                        }
                        bufferEmpty = true;
                    }
                }

                if (!bufferEmpty)
                {
                    execute();
                    if (rc.Abort)
                    {
                        return(rc);
                    }
                }

                void execute()
                {
                    cmd.ExecuteNonQuery();

                    rc.RowsCopied = count;

                    if (sw.Elapsed.TotalSeconds > options.BulkCopyTimeout)
                    {
                        traceAction(
                            dataConnection,
                            () => $"INSERT BULK {tableName} TIMEOUT AFTER {sw.Elapsed.TotalSeconds} SECONDS" + Environment.NewLine,
                            () => (int)rc.RowsCopied);

                        rc.Abort = true;

                        return;
                    }

                    if (options.NotifyAfter > 0 && notificationBatchCount > options.NotifyAfter)
                    {
                        options.RowsCopiedCallback?.Invoke(rc);
                        notificationBatchCount = 0;
                    }

                    if (rc.Abort)
                    {
                        traceAction(
                            dataConnection,
                            () => $"INSERT BULK {tableName} ABORTED BY USER" + Environment.NewLine,
                            () => (int)rc.RowsCopied);

                        return;
                    }
                }
            }

            return(rc);
        }
        protected override BulkCopyRowsCopied ProviderSpecificCopy <T>(
            DataConnection dataConnection,
            BulkCopyOptions options,
            IEnumerable <T> source)
        {
            if (dataConnection == null)
            {
                throw new ArgumentNullException("dataConnection");
            }

            if (dataConnection.Transaction == null)
            {
                var sqlBuilder = dataConnection.DataProvider.CreateSqlBuilder();
                var descriptor = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
                var tableName  = GetTableName(sqlBuilder, options, descriptor);
                if (_bulkCopyCreator == null)
                {
                    throw new NotImplementedException("Not able to do bulk copy in DB2iSeries Provider.");
                }
                if (_bulkCopyCreator != null)
                {
                    var columns   = descriptor.Columns.Where(c => !c.SkipOnInsert || options.KeepIdentity == true && c.IsIdentity).ToList();
                    var rd        = new BulkCopyReader(dataConnection.DataProvider, dataConnection.MappingSchema, columns, source);
                    var rc        = new BulkCopyRowsCopied();
                    var bcOptions = 0;                     // Default
                    if (options.KeepIdentity == true)
                    {
                        bcOptions |= 1;                                                   // KeepIdentity = 1, TableLock = 2, Truncate = 4,
                    }
                    if (options.TableLock == true)
                    {
                        bcOptions |= 2;
                    }

                    using (var bc = _bulkCopyCreator(dataConnection.Connection, bcOptions))
                    {
                        dynamic dbc         = bc;
                        var     notifyAfter = options.NotifyAfter == 0 && options.MaxBatchSize.HasValue ?
                                              options.MaxBatchSize.Value : options.NotifyAfter;
                        if (notifyAfter != 0 && options.RowsCopiedCallback != null)
                        {
                            if (_bulkCopySubscriber == null)
                            {
                                _bulkCopySubscriber = CreateBulkCopySubscriber(bc, "DB2iSeriesRowsCopied");
                            }
                            dbc.NotifyAfter = notifyAfter;
                            _bulkCopySubscriber(bc, arg =>
                            {
                                dynamic darg  = arg;
                                rc.RowsCopied = darg.RowsCopied;
                                options.RowsCopiedCallback(rc);
                                if (rc.Abort)
                                {
                                    darg.Abort = true;
                                }
                            });
                        }
                        if (options.BulkCopyTimeout.HasValue)
                        {
                            dbc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                        }
                        dbc.DestinationTableName = tableName;
                        for (var i = 0; i < columns.Count; i++)
                        {
                            dbc.ColumnMappings.Add((dynamic)_columnMappingCreator(i, columns[i].ColumnName));
                        }
                        dbc.WriteToServer(rd);
                    }
                    rc.RowsCopied = rd.Count;
                    return(rc);
                }
            }
            return(MultipleRowsCopy(dataConnection, options, source));
        }
Exemplo n.º 19
0
        protected override BulkCopyRowsCopied ProviderSpecificCopy <T>(
            ITable <T> table,
            BulkCopyOptions options,
            IEnumerable <T> source)
        {
            // database name is not a part of table FQN in oracle
            var serverName = options.ServerName ?? table.ServerName;

            if (table.DataContext is DataConnection dataConnection && _provider.Adapter.BulkCopy != null &&
                serverName == null)
            {
                var connection = _provider.TryGetProviderConnection(dataConnection.Connection, dataConnection.MappingSchema);

                if (connection != null)
                {
                    var ed      = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
                    var columns = ed.Columns.Where(c => !c.SkipOnInsert || options.KeepIdentity == true && c.IsIdentity).ToList();
                    var sb      = _provider.CreateSqlBuilder(dataConnection.MappingSchema);

                    // ODP.NET doesn't bulk copy doesn't work if columns that require escaping:
                    // - if escaping applied, pre-flight validation fails as it performs uppercase comparison and quotes make it fail with
                    //   InvalidOperationException: Column mapping is invalid
                    // - if escaping not applied - if fails as expected on server, because it treats passed name as uppercased name
                    //   and gives "ORA-00904: "STRINGVALUE": invalid identifier" error
                    // That's quite common error in bulk copy implementation error by providers...
                    var supported = true;
                    foreach (var column in columns)
                    {
                        if (column.ColumnName != sb.ConvertInline(column.ColumnName, ConvertType.NameToQueryField))
                        {
                            // fallback to sql-based copy
                            // TODO: we should add support for by-ordinal column mapping to workaround it
                            supported = false;
                            break;
                        }
                    }

                    if (supported)
                    {
                        var rd     = new BulkCopyReader <T>(dataConnection, columns, source);
                        var sqlopt = OracleProviderAdapter.OracleBulkCopyOptions.Default;
                        var rc     = new BulkCopyRowsCopied();

                        var tableName  = sb.ConvertInline(options.TableName ?? table.TableName, ConvertType.NameToQueryTable);
                        var schemaName = options.SchemaName ?? table.SchemaName;
                        if (schemaName != null)
                        {
                            schemaName = sb.ConvertInline(schemaName, ConvertType.NameToSchema);
                        }

                        if (options.UseInternalTransaction == true)
                        {
                            sqlopt |= OracleProviderAdapter.OracleBulkCopyOptions.UseInternalTransaction;
                        }

                        using (var bc = _provider.Adapter.BulkCopy.Create(connection, sqlopt))
                        {
                            var notifyAfter = options.NotifyAfter == 0 && options.MaxBatchSize.HasValue
                                                        ? options.MaxBatchSize.Value
                                                        : options.NotifyAfter;

                            if (notifyAfter != 0 && options.RowsCopiedCallback != null)
                            {
                                bc.NotifyAfter = options.NotifyAfter;

                                bc.OracleRowsCopied += (sender, args) =>
                                {
                                    rc.RowsCopied = args.RowsCopied;
                                    options.RowsCopiedCallback(rc);
                                    if (rc.Abort)
                                    {
                                        args.Abort = true;
                                    }
                                };
                            }

                            if (options.MaxBatchSize.HasValue)
                            {
                                bc.BatchSize = options.MaxBatchSize.Value;
                            }

                            if (options.BulkCopyTimeout.HasValue)
                            {
                                bc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                            }
                            else if (Configuration.Data.BulkCopyUseConnectionCommandTimeout)
                            {
                                bc.BulkCopyTimeout = connection.ConnectionTimeout;
                            }

                            bc.DestinationTableName  = tableName;
                            bc.DestinationSchemaName = schemaName;

                            for (var i = 0; i < columns.Count; i++)
                            {
                                bc.ColumnMappings.Add(_provider.Adapter.BulkCopy.CreateColumnMapping(i, columns[i].ColumnName));
                            }

                            TraceAction(
                                dataConnection,
                                () => "INSERT BULK " + (schemaName == null ? tableName : schemaName + "." + tableName) + "(" + string.Join(", ", columns.Select(x => x.ColumnName)) + ")" + Environment.NewLine,
                                () => { bc.WriteToServer(rd); return(rd.Count); });
                        }

                        if (rc.RowsCopied != rd.Count)
                        {
                            rc.RowsCopied = rd.Count;

                            if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                            {
                                options.RowsCopiedCallback(rc);
                            }
                        }

                        return(rc);
                    }
                }
            }


            return(MultipleRowsCopy(table, options, source));
        }
Exemplo n.º 20
0
        internal static BulkCopyRowsCopied ProviderSpecificCopyImpl <T>(
            ITable <T> table,
            BulkCopyOptions options,
            IEnumerable <T> source,
            DataConnection dataConnection,
            DbConnection connection,
            DB2ProviderAdapter.BulkCopyAdapter bulkCopy,
            Action <DataConnection, Func <string>, Func <int> > traceAction)
            where T : notnull
        {
            var descriptor = table.DataContext.MappingSchema.GetEntityDescriptor(typeof(T));
            var columns    = descriptor.Columns.Where(c => !c.SkipOnInsert || options.KeepIdentity == true && c.IsIdentity).ToList();
            var rd         = new BulkCopyReader <T>(dataConnection, columns, source);
            var rc         = new BulkCopyRowsCopied();
            var sqlBuilder = dataConnection.DataProvider.CreateSqlBuilder(table.DataContext.MappingSchema);
            var tableName  = GetTableName(sqlBuilder, options, table);

            var bcOptions = DB2BulkCopyOptions.Default;

            if (options.KeepIdentity == true)
            {
                bcOptions |= DB2BulkCopyOptions.KeepIdentity;
            }
            if (options.TableLock == true)
            {
                bcOptions |= DB2BulkCopyOptions.TableLock;
            }

            using (var bc = bulkCopy.Create(connection, bcOptions))
            {
                var notifyAfter = options.NotifyAfter == 0 && options.MaxBatchSize.HasValue ?
                                  options.MaxBatchSize.Value : options.NotifyAfter;

                if (notifyAfter != 0 && options.RowsCopiedCallback != null)
                {
                    bc.NotifyAfter = notifyAfter;

                    bc.DB2RowsCopied += (sender, args) =>
                    {
                        rc.RowsCopied = args.RowsCopied;
                        options.RowsCopiedCallback(rc);
                        if (rc.Abort)
                        {
                            args.Abort = true;
                        }
                    };
                }

                if (options.BulkCopyTimeout.HasValue)
                {
                    bc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                }
                else if (Configuration.Data.BulkCopyUseConnectionCommandTimeout)
                {
                    bc.BulkCopyTimeout = connection.ConnectionTimeout;
                }

                bc.DestinationTableName = tableName;

                for (var i = 0; i < columns.Count; i++)
                {
                    bc.ColumnMappings.Add(bulkCopy.CreateColumnMapping(i, sqlBuilder.ConvertInline(columns[i].ColumnName, SqlProvider.ConvertType.NameToQueryField)));
                }

                traceAction(
                    dataConnection,
                    () => "INSERT BULK " + tableName + Environment.NewLine,
                    () => { bc.WriteToServer(rd); return(rd.Count); });
            }

            if (rc.RowsCopied != rd.Count)
            {
                rc.RowsCopied = rd.Count;

                if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                {
                    options.RowsCopiedCallback(rc);
                }
            }

            return(rc);
        }
Exemplo n.º 21
0
        protected override BulkCopyRowsCopied ProviderSpecificCopy <T>(
            [JetBrains.Annotations.NotNull] DataConnection dataConnection,
            BulkCopyOptions options,
            IEnumerable <T> source)
        {
            if (dataConnection == null)
            {
                throw new ArgumentNullException("dataConnection");
            }

            var connection = dataConnection.Connection as SqlConnection;

            if (connection != null)
            {
                var ed      = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
                var columns = ed.Columns.Where(c => !c.SkipOnInsert || options.KeepIdentity == true && c.IsIdentity).ToList();
                var sb      = _dataProvider.CreateSqlBuilder();
                var rd      = new BulkCopyReader(_dataProvider, columns, source);
                var sqlopt  = SqlBulkCopyOptions.Default;
                var rc      = new BulkCopyRowsCopied();

                if (options.CheckConstraints == true)
                {
                    sqlopt |= SqlBulkCopyOptions.CheckConstraints;
                }
                if (options.KeepIdentity == true)
                {
                    sqlopt |= SqlBulkCopyOptions.KeepIdentity;
                }
                if (options.TableLock == true)
                {
                    sqlopt |= SqlBulkCopyOptions.TableLock;
                }
                if (options.KeepNulls == true)
                {
                    sqlopt |= SqlBulkCopyOptions.KeepNulls;
                }
                if (options.FireTriggers == true)
                {
                    sqlopt |= SqlBulkCopyOptions.FireTriggers;
                }
                if (options.UseInternalTransaction == true)
                {
                    sqlopt |= SqlBulkCopyOptions.UseInternalTransaction;
                }

                using (var bc = new SqlBulkCopy(connection, sqlopt, (SqlTransaction)dataConnection.Transaction))
                {
                    if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                    {
                        bc.NotifyAfter = options.NotifyAfter;

                        bc.SqlRowsCopied += (sender, e) =>
                        {
                            rc.RowsCopied = e.RowsCopied;
                            options.RowsCopiedCallback(rc);
                            if (rc.Abort)
                            {
                                e.Abort = true;
                            }
                        };
                    }

                    if (options.MaxBatchSize.HasValue)
                    {
                        bc.BatchSize = options.MaxBatchSize.Value;
                    }
                    if (options.BulkCopyTimeout.HasValue)
                    {
                        bc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                    }

                    var sqlBuilder = _dataProvider.CreateSqlBuilder();
                    var descriptor = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
                    var tableName  = GetTableName(sqlBuilder, descriptor);

                    bc.DestinationTableName = tableName;

                    for (var i = 0; i < columns.Count; i++)
                    {
                        bc.ColumnMappings.Add(new SqlBulkCopyColumnMapping(
                                                  i,
                                                  sb.Convert(columns[i].ColumnName, ConvertType.NameToQueryField).ToString()));
                    }

                    bc.WriteToServer(rd);
                }

                if (rc.RowsCopied != rd.Count)
                {
                    rc.RowsCopied = rd.Count;

                    if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                    {
                        options.RowsCopiedCallback(rc);
                    }
                }

                return(rc);
            }

            return(MultipleRowsCopy(dataConnection, options, source));
        }
Exemplo n.º 22
0
        protected override BulkCopyRowsCopied ProviderSpecificCopy <T>(
            [JetBrains.Annotations.NotNull] DataConnection dataConnection,
            BulkCopyOptions options,
            IEnumerable <T> source)
        {
            if (dataConnection == null)
            {
                throw new ArgumentNullException("dataConnection");
            }

            var sqlBuilder = dataConnection.DataProvider.CreateSqlBuilder();
            var descriptor = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
            var tableName  = GetTableName(sqlBuilder, options, descriptor);

            if (dataConnection.Transaction == null)
            {
                if (_bulkCopyCreator == null)
                {
                    var clientNamespace    = ((OracleDataProvider)dataConnection.DataProvider).AssemblyName + ".Client.";
                    var bulkCopyType       = _connectionType.AssemblyEx().GetType(clientNamespace + "OracleBulkCopy", false);
                    var bulkCopyOptionType = _connectionType.AssemblyEx().GetType(clientNamespace + "OracleBulkCopyOptions", false);
                    var columnMappingType  = _connectionType.AssemblyEx().GetType(clientNamespace + "OracleBulkCopyColumnMapping", false);

                    if (bulkCopyType != null)
                    {
                        _bulkCopyCreator      = CreateBulkCopyCreator(_connectionType, bulkCopyType, bulkCopyOptionType);
                        _columnMappingCreator = CreateColumnMappingCreator(columnMappingType);
                    }
                }

                if (_bulkCopyCreator != null)
                {
                    var columns = descriptor.Columns.Where(c => !c.SkipOnInsert).ToList();
                    var rd      = new BulkCopyReader(_dataProvider, columns, source);
                    var rc      = new BulkCopyRowsCopied();

                    var bcOptions = 0;                     // Default

                    if (options.UseInternalTransaction == true)
                    {
                        bcOptions |= 1;                                                             // UseInternalTransaction = 1,
                    }
                    using (var bc = _bulkCopyCreator(dataConnection.Connection, bcOptions))
                    {
                        dynamic dbc = bc;

                        var notifyAfter = options.NotifyAfter == 0 && options.MaxBatchSize.HasValue ?
                                          options.MaxBatchSize.Value : options.NotifyAfter;

                        if (notifyAfter != 0 && options.RowsCopiedCallback != null)
                        {
                            if (_bulkCopySubscriber == null)
                            {
                                _bulkCopySubscriber = CreateBulkCopySubscriber(bc, "OracleRowsCopied");
                            }

                            dbc.NotifyAfter = notifyAfter;

                            _bulkCopySubscriber(bc, arg =>
                            {
                                dynamic darg  = arg;
                                rc.RowsCopied = darg.RowsCopied;
                                options.RowsCopiedCallback(rc);
                                if (rc.Abort)
                                {
                                    darg.Abort = true;
                                }
                            });
                        }

                        if (options.MaxBatchSize.HasValue)
                        {
                            dbc.BatchSize = options.MaxBatchSize.Value;
                        }
                        if (options.BulkCopyTimeout.HasValue)
                        {
                            dbc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                        }

                        dbc.DestinationTableName = tableName;

                        for (var i = 0; i < columns.Count; i++)
                        {
                            dbc.ColumnMappings.Add((dynamic)_columnMappingCreator(i, columns[i].ColumnName));
                        }

                        TraceAction(
                            dataConnection,
                            "INSERT BULK " + tableName + Environment.NewLine,
                            () => { dbc.WriteToServer(rd); return(rd.Count); });
                    }

                    if (rc.RowsCopied != rd.Count)
                    {
                        rc.RowsCopied = rd.Count;

                        if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                        {
                            options.RowsCopiedCallback(rc);
                        }
                    }

                    return(rc);
                }
            }

            options.BulkCopyType = BulkCopyType.MultipleRows;

            return(MultipleRowsCopy(dataConnection, options, source));
        }
Exemplo n.º 23
0
        protected override BulkCopyRowsCopied ProviderSpecificCopy <T>(
            ITable <T> table,
            BulkCopyOptions options,
            IEnumerable <T> source)
        {
            if (_provider.Adapter.BulkCopy != null && table.DataContext is DataConnection dataConnection)
            {
                var connection = _provider.TryGetProviderConnection(dataConnection.Connection, dataConnection.MappingSchema);

                var transaction = dataConnection.Transaction;
                if (connection != null && transaction != null)
                {
                    transaction = _provider.TryGetProviderTransaction(transaction, dataConnection.MappingSchema);
                }

                if (connection != null && (dataConnection.Transaction == null || transaction != null))
                {
                    var ed      = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
                    var columns = ed.Columns.Where(c => !c.SkipOnInsert || options.KeepIdentity == true && c.IsIdentity).ToList();
                    var sb      = _provider.CreateSqlBuilder(dataConnection.MappingSchema);
                    var rc      = new BulkCopyRowsCopied();

                    var bc = _provider.Adapter.BulkCopy.Create(connection, transaction);
                    if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                    {
                        bc.NotifyAfter = options.NotifyAfter;

                        bc.MySqlRowsCopied += (sender, args) =>
                        {
                            rc.RowsCopied += args.RowsCopied;
                            options.RowsCopiedCallback(rc);
                            if (rc.Abort)
                            {
                                args.Abort = true;
                            }
                        };
                    }

                    if (options.BulkCopyTimeout.HasValue)
                    {
                        bc.BulkCopyTimeout = options.BulkCopyTimeout.Value;
                    }

                    var tableName = GetTableName(sb, options, table);

                    bc.DestinationTableName = GetTableName(sb, options, table);

                    for (var i = 0; i < columns.Count; i++)
                    {
                        bc.AddColumnMapping(_provider.Adapter.BulkCopy.CreateColumnMapping(i, columns[i].ColumnName));
                    }

                    // emulate missing BatchSize property
                    // this is needed, because MySql fails on big batches, so users should be able to limit batch size
                    foreach (var batch in EnumerableHelper.Batch(source, options.MaxBatchSize ?? int.MaxValue))
                    {
                        var rd = new BulkCopyReader(dataConnection, columns, batch);

                        TraceAction(
                            dataConnection,
                            () => "INSERT BULK " + tableName + "(" + string.Join(", ", columns.Select(x => x.ColumnName)) + Environment.NewLine,
                            () => { bc.WriteToServer(rd); return(rd.Count); });

                        rc.RowsCopied += rd.Count;
                    }

                    if (options.NotifyAfter != 0 && options.RowsCopiedCallback != null)
                    {
                        options.RowsCopiedCallback(rc);
                    }

                    return(rc);
                }
            }

            return(MultipleRowsCopy(table, options, source));
        }