Exemplo n.º 1
0
        /// <summary>
        /// Creates a clone of the database using another SqlAgent.
        /// </summary>
        /// <param name="cloneManager">an SQL schema manager to use when creating clone database</param>
        /// <param name="schemaToUse">a database schema to use (enforce),
        /// if null the schema ir read from the database cloned</param>
        /// <param name="ct">a cancelation token (if any)</param>
        /// <param name="progress">a progress callback (if any)</param>
        public async Task CloneDatabase(SchemaManagerBase cloneManager, DbSchema schemaToUse,
                                        IProgress <DbCloneProgressArgs> progress, CancellationToken ct)
        {
            if (cloneManager.IsNull())
            {
                throw new ArgumentNullException(nameof(cloneManager));
            }

            progress?.Report(new DbCloneProgressArgs(DbCloneProgressArgs.Stage.FetchingSchema, string.Empty, 0));

            if (schemaToUse.IsNull())
            {
                schemaToUse = await GetDbSchemaAsync(ct).ConfigureAwait(false);
            }

            if (CloneCanceled(progress, ct))
            {
                return;
            }

            progress?.Report(new DbCloneProgressArgs(DbCloneProgressArgs.Stage.CreatingSchema, string.Empty, 0));

            await cloneManager.CreateDatabaseAsync(schemaToUse).ConfigureAwait(false);

            if (CloneCanceled(progress, ct))
            {
                return;
            }

            await cloneManager.Agent.ExecuteInTransactionAsync(async (cancellationToken) =>
            {
                await cloneManager.DisableForeignKeysForCurrentTransactionAsync().ConfigureAwait(false);
                await CopyData(schemaToUse, cloneManager, progress, cancellationToken).ConfigureAwait(false);
            }, ct).ConfigureAwait(false);

            if (!ct.IsCancellationRequested)
            {
                progress?.Report(
                    new DbCloneProgressArgs(DbCloneProgressArgs.Stage.Completed, string.Empty, 100));
            }
        }
Exemplo n.º 2
0
 /// <summary>
 /// Invokes protected <see cref="InsertTableData">InsertTableData</see>
 /// method on target SqlAgent. Used to bypass cross instance protected method
 /// access limitation.
 /// </summary>
 /// <param name="target">the SqlAgent to invoke the <see cref="InsertTableData">InsertTableData</see>
 /// method on</param>
 /// <param name="table">a schema of the table to insert the data to</param>
 /// <param name="reader">an IDataReader to read the table data from</param>
 /// <remarks>Required for <see cref="CloneDatabase">CloneDatabase</see> infrastructure.
 /// The insert is performed using a transaction that is already initiated by the
 /// <see cref="CloneDatabase">CloneDatabase</see>.</remarks>
 protected static Task <long> CallInsertTableDataAsync(SchemaManagerBase target, DbTableSchema table,
                                                       IDataReader reader, long totalRowCount, long currentRow, int currentProgress,
                                                       IProgress <DbCloneProgressArgs> progress, CancellationToken ct)
 {
     return(target.InsertTableDataAsync(table, reader, totalRowCount, currentRow, currentProgress, progress, ct));
 }
Exemplo n.º 3
0
 /// <summary>
 /// Copies table data from the current SqlAgent instance to the target SqlAgent instance.
 /// </summary>
 /// <param name="schema">a schema of the database to copy the data</param>
 /// <param name="targetManager">the target Sql schema manager to copy the data to</param>
 /// <remarks>Required for <see cref="CloneDatabase">CloneDatabase</see> infrastructure.
 /// Basicaly iterates tables, selects data, creates an IDataReader for the table and passes it to the
 /// <see cref="InsertTableData">InsertTableData</see> method of the target SqlAgent.</remarks>
 protected abstract Task CopyData(DbSchema schema, SchemaManagerBase targetManager,
                                  IProgress <DbCloneProgressArgs> progress, CancellationToken ct);