Skip to content

Commit c4434fe

Browse files
committed
- Updated version to 2.4.2 for release to Nuget!
- Add Support to manually control if Materialized Loading tables are cleaned-up/removed when using `SchemaCopyMode.OutsideTransactionAvoidSchemaLocks` via `materializeDataContext.DisableMaterializedStagingTableCleanup()`; always enabled by default and throws an `InvalidOperationException` if if SchemaCopyMode.InsideTransactionAllowSchemaLocks is used. This provides support for advanced debugging and control flow support. - Improved SqlBulkHelpers Configuration API to now provide Clone() and Configure() methods to more easily copy/clone existing configuration and change values is specific instances; including copy/clone of the Defaults for unique exeuctions.
1 parent 21916f8 commit c4434fe

File tree

8 files changed

+168
-17
lines changed

8 files changed

+168
-17
lines changed

NetStandard.SqlBulkHelpers/MaterializedData/IMaterializeDataContext.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ public interface IMaterializeDataContext
2626
TableNameTerm GetLoadingTableName(string tableName);
2727
TableNameTerm GetLoadingTableName<TModel>();
2828
TableNameTerm GetLoadingTableName(Type modelType);
29-
void CancelMaterializationProcess();
3029
bool IsCancelled { get; }
30+
IMaterializeDataContext CancelMaterializationProcess();
31+
bool IsMaterializedLoadingTableCleanupEnabled { get; }
32+
IMaterializeDataContext DisableMaterializedLoadingTableCleanup();
3133
}
3234
}

NetStandard.SqlBulkHelpers/MaterializedData/MaterializeDataContext.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public class MaterializeDataContext : IMaterializeDataContextCompletionSource, I
1414
protected ISqlBulkHelpersConfig BulkHelpersConfig { get; }
1515
protected bool IsDisposed { get; set; } = false;
1616
public bool IsCancelled { get; protected set; } = false;
17+
public bool IsMaterializedLoadingTableCleanupEnabled { get; protected set; } = true;
1718

1819
protected List<SqlBulkHelpersTableDefinition> TablesWithFullTextIndexesRemoved { get; set; } = new List<SqlBulkHelpersTableDefinition>();
1920

@@ -25,7 +26,30 @@ public class MaterializeDataContext : IMaterializeDataContextCompletionSource, I
2526

2627
public MaterializationTableInfo this[Type modelType] => FindMaterializationTableInfoCaseInsensitive(modelType);
2728

28-
public void CancelMaterializationProcess() => IsCancelled = true;
29+
/// <summary>
30+
/// Provides ability to manually control if materialization process is Cancelled for advanced validation and control flow support.
31+
/// </summary>
32+
/// <returns></returns>
33+
public IMaterializeDataContext CancelMaterializationProcess()
34+
{
35+
IsCancelled = true;
36+
return this;
37+
}
38+
39+
/// <summary>
40+
/// Provides ability to manually control if Materialized Loading tables are cleaned-up/removed when using `SchemaCopyMode.OutsideTransactionAvoidSchemaLocks`
41+
/// for advanced debugging and control flow support; always enabled by default and throws an `InvalidOperationException` if if SchemaCopyMode.InsideTransactionAllowSchemaLocks is used.
42+
/// </summary>
43+
/// <returns></returns>
44+
/// <exception cref="InvalidOperationException"></exception>
45+
public IMaterializeDataContext DisableMaterializedLoadingTableCleanup()
46+
{
47+
if (BulkHelpersConfig.MaterializedDataSchemaCopyMode == SchemaCopyMode.InsideTransactionAllowSchemaLocks)
48+
throw new InvalidOperationException("You cannot disable the cleanup of Materialized Loading tables when using SchemaCopyMode.InsideTransactionAllowSchemaLocks.");
49+
50+
IsMaterializedLoadingTableCleanupEnabled = false;
51+
return this;
52+
}
2953

3054
public TableNameTerm GetLoadingTableName(string tableName)
3155
{

NetStandard.SqlBulkHelpers/MaterializedData/MaterializeDataHelper.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,12 @@ public async Task<IMaterializeDataContext> CleanupMaterializeDataProcessAsync(Sq
7272
//Explicitly clean up all Loading/Discarding Tables (contains old data) to free resources -- this leaves us with only the (new) Live Table in place!
7373
foreach (var materializationTableInfo in materializationTables)
7474
{
75-
switchScriptBuilder
76-
//Finally cleanup the Loading and Discarding tables...
77-
.DropTableIfExists(materializationTableInfo.LoadingTable)
78-
.DropTableIfExists(materializationTableInfo.DiscardingTable);
75+
//ALWAYS cleanup the Discarding tables...
76+
switchScriptBuilder.DropTableIfExists(materializationTableInfo.DiscardingTable);
77+
78+
//IF enabled (default is always Enabled) then cleanup up the Loading Tables
79+
if (materializedDataContext.IsMaterializedLoadingTableCleanupEnabled)
80+
switchScriptBuilder.DropTableIfExists(materializationTableInfo.LoadingTable);
7981
}
8082

8183
await sqlTransaction.ExecuteMaterializedDataSqlScriptAsync(

NetStandard.SqlBulkHelpers/NetStandard.SqlBulkHelpers.csproj

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,22 @@
88
<PackageLicenseExpression>MIT</PackageLicenseExpression>
99
<Authors>BBernard / CajunCoding</Authors>
1010
<Company>CajunCoding</Company>
11-
<Version>2.4.1</Version>
11+
<Version>2.4.2</Version>
1212
<PackageProjectUrl>https://github.com/cajuncoding/SqlBulkHelpers</PackageProjectUrl>
1313
<RepositoryUrl>https://github.com/cajuncoding/SqlBulkHelpers</RepositoryUrl>
1414
<Description>A library for easy, efficient and high performance bulk insert and update of data, into a Sql Database, from .Net applications. By leveraging the power of the SqlBulkCopy classes with added support for Identity primary key table columns this library provides a greatly simplified interface to process Identity based Entities with Bulk Performance with the wide compatibility of .NetStandard 2.0.</Description>
1515
<PackageTags>sql server database table bulk insert update identity column sqlbulkcopy orm dapper linq2sql materialization materialized data view materialized-data materialized-view sync replication replica readonly</PackageTags>
1616
<PackageReleaseNotes>
17+
- Add Support to manually control if Materialized Loading tables are cleaned-up/removed when using `SchemaCopyMode.OutsideTransactionAvoidSchemaLocks` via `materializeDataContext.DisableMaterializedStagingTableCleanup()`;
18+
always enabled by default and throws an `InvalidOperationException` if if SchemaCopyMode.InsideTransactionAllowSchemaLocks is used. This provides support for advanced debugging and control flow support.
19+
- Improved SqlBulkHelpers Configuration API to now provide Clone() and Configure() methods to more easily copy/clone existing configuration and change values is specific instances;
20+
including copy/clone of the Defaults for unique exeuctions.
1721
- Added support to load Table Schema for Temp Tables (basic Schema details needed for BulkInsert or Update, etc. to allow Bulk Loading Temp Tables!
1822
- Improved Error message for when custom SQL Merge Match qualifiers are specified but DB Schema may have changed making them invalid or missing from Cached schema.
23+
- Added new explicit CopyTableDataAsync() APIs which enable explicit copying of data between two tables on matching columns (automatically detected by column Name and Data Type).
24+
- Added new Materialized Data Configuration value MaterializedDataLoadingTableDataCopyMode to control whether the materialized data process automatically copies data into the Loading Tables after cloning. This helps to greatly simplify new use cases where data must be merged (and preserved) during the materialization process.
1925

2026
Prior Relese Notes:
21-
-Added new explicit CopyTableDataAsync() APIs which enable explicit copying of data between two tables on matching columns (automatically detected by column Name and Data Type).
22-
-Added new Materialized Data Configuration value MaterializedDataLoadingTableDataCopyMode to control whether the materialized data process automatically copies data into the Loading Tables after cloning. This helps to greatly simplify new use cases where data must be merged (and preserved) during the materialization process.
2327
- Fixed bug with Sql Bulk Insert/Update processing with Model Properties that have mapped database names via mapping attribute (e.g. [SqlBulkColumn("")], [Map("")], [Column("")], etc.).
2428
- Changed default behaviour to no longer clone tables/schema inside a Transaction which creates a full Schema Lock -- as this greatly impacts Schema aware ORMs such as SqlBulkHelpers, RepoDb, etc.
2529
- New separate methods is now added to handle the CleanupMaterializeDataProcessAsync() but must be explicitly called as it is no longer implicitly called with FinishMaterializeDataProcessAsync().

NetStandard.SqlBulkHelpers/SqlBulkHelpersConfig.cs

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,54 @@ public interface ISqlBulkHelpersConfig
5252
int MaxConcurrentConnections { get; }
5353
bool IsConcurrentConnectionProcessingEnabled { get; }
5454
bool IsFullTextIndexHandlingEnabled { get; }
55+
56+
ISqlBulkHelpersConfig Clone();
57+
ISqlBulkHelpersConfig Configure(Action<SqlBulkHelpersConfig> configAction);
5558
}
5659

5760
public class SqlBulkHelpersConfig : ISqlBulkHelpersConfig
5861
{
5962
public static ISqlBulkHelpersConfig DefaultConfig { get; private set; } = new SqlBulkHelpersConfig();
6063

61-
public static SqlBulkHelpersConfig Create(Action<SqlBulkHelpersConfig> configAction)
64+
// Constructor for cloning
65+
private SqlBulkHelpersConfig(ISqlBulkHelpersConfig otherConfigToClone = null)
6266
{
63-
configAction.AssertArgumentIsNotNull(nameof(configAction));
67+
if (otherConfigToClone == null) return;
68+
69+
// Copy property values from the other instance
70+
this.SqlBulkBatchSize = otherConfigToClone.SqlBulkBatchSize;
71+
this.SqlBulkPerBatchTimeoutSeconds = otherConfigToClone.SqlBulkPerBatchTimeoutSeconds;
72+
this.IsSqlBulkTableLockEnabled = otherConfigToClone.IsSqlBulkTableLockEnabled;
73+
this.SqlBulkCopyOptions = otherConfigToClone.SqlBulkCopyOptions;
74+
this.DbSchemaLoaderQueryTimeoutSeconds = otherConfigToClone.DbSchemaLoaderQueryTimeoutSeconds;
75+
this.MaterializeDataStructureProcessingTimeoutSeconds = otherConfigToClone.MaterializeDataStructureProcessingTimeoutSeconds;
76+
this.MaterializedDataSwitchTableWaitTimeoutMinutes = otherConfigToClone.MaterializedDataSwitchTableWaitTimeoutMinutes;
77+
this.MaterializedDataSwitchTimeoutAction = otherConfigToClone.MaterializedDataSwitchTimeoutAction;
78+
this.MaterializedDataSchemaCopyMode = otherConfigToClone.MaterializedDataSchemaCopyMode;
79+
this.MaterializedDataLoadingTableDataCopyMode = otherConfigToClone.MaterializedDataLoadingTableDataCopyMode;
80+
this.MaterializedDataMakeSchemaCopyNamesUnique = otherConfigToClone.MaterializedDataMakeSchemaCopyNamesUnique;
81+
this.MaterializedDataLoadingSchema = otherConfigToClone.MaterializedDataLoadingSchema;
82+
this.MaterializedDataLoadingTablePrefix = otherConfigToClone.MaterializedDataLoadingTablePrefix;
83+
this.MaterializedDataLoadingTableSuffix = otherConfigToClone.MaterializedDataLoadingTableSuffix;
84+
this.MaterializedDataDiscardingSchema = otherConfigToClone.MaterializedDataDiscardingSchema;
85+
this.MaterializedDataDiscardingTablePrefix = otherConfigToClone.MaterializedDataDiscardingTablePrefix;
86+
this.MaterializedDataDiscardingTableSuffix = otherConfigToClone.MaterializedDataDiscardingTableSuffix;
87+
this.IsCloningIdentitySeedValueEnabled = otherConfigToClone.IsCloningIdentitySeedValueEnabled;
88+
this.ConcurrentConnectionFactory = otherConfigToClone.ConcurrentConnectionFactory;
89+
this.MaxConcurrentConnections = otherConfigToClone.MaxConcurrentConnections;
90+
this.IsFullTextIndexHandlingEnabled = otherConfigToClone.IsFullTextIndexHandlingEnabled;
91+
}
92+
93+
public static SqlBulkHelpersConfig Create(Action<SqlBulkHelpersConfig> configAction, ISqlBulkHelpersConfig otherConfigToClone = null)
94+
=> (SqlBulkHelpersConfig)new SqlBulkHelpersConfig(otherConfigToClone).Configure(configAction);
95+
96+
public ISqlBulkHelpersConfig Clone() => new SqlBulkHelpersConfig(this);
6497

65-
var newConfig = new SqlBulkHelpersConfig();
66-
configAction.Invoke(newConfig);
67-
return newConfig;
98+
public ISqlBulkHelpersConfig Configure(Action<SqlBulkHelpersConfig> configAction)
99+
{
100+
configAction.AssertArgumentIsNotNull(nameof(configAction));
101+
configAction.Invoke(this);
102+
return this;
68103
}
69104

70105
/// <summary>
@@ -125,6 +160,8 @@ public void EnableConcurrentSqlConnectionProcessing(
125160
this.IsFullTextIndexHandlingEnabled = IsFullTextIndexHandlingEnabled || enableFullTextIndexHandling;
126161
}
127162

163+
#region All Public Properties / Config Setttings...
164+
128165
public int SqlBulkBatchSize { get; set; } = 2000; //General guidance is that 2000-5000 is efficient enough.
129166

130167
public int SqlBulkPerBatchTimeoutSeconds { get; set; }
@@ -186,5 +223,7 @@ public int MaxConcurrentConnections
186223
/// Recommended to use the SqlBulkHelpersConfig.EnableConcurrentSqlConnectionProcessing() convenience method(s) to enable this more easily!
187224
/// </summary>
188225
public bool IsFullTextIndexHandlingEnabled { get; set; } = false;
226+
227+
#endregion
189228
}
190229
}

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,21 @@ public class TestDataService
215215
## Nuget Package
216216
To use in your project, add the [SqlBulkHelpers NuGet package](https://www.nuget.org/packages/SqlBulkHelpers/) to your project.
217217

218+
### v2.4.2 Release Notes:
219+
- Add Support to manually control if Materialized Loading tables are cleaned-up/removed when using `SchemaCopyMode.OutsideTransactionAvoidSchemaLocks` via `materializeDataContext.DisableMaterializedStagingTableCleanup()`;
220+
always enabled by default and throws an `InvalidOperationException` if if SchemaCopyMode.InsideTransactionAllowSchemaLocks is used. This provides support for advanced debugging and control flow support.
221+
- Improved SqlBulkHelpers Configuration API to now provide Clone() and Configure() methods to more easily copy/clone existing configuration and change values is specific instances;
222+
including copy/clone of the Defaults for unique exeuctions.
223+
224+
### v2.4.1 Release Notes:
225+
- Added support to load Table Schema for Temp Tables (basic Schema details needed for BulkInsert or Update, etc. to allow Bulk Loading Temp Tables!
226+
- Improved Error message for when custom SQL Merge Match qualifiers are specified but DB Schema may have changed making them invalid or missing from Cached schema.
227+
228+
### v2.4.0 Release Notes:
229+
- Added new explicit CopyTableDataAsync() APIs which enable explicit copying of data between two tables on matching columns (automatically detected by column Name and Data Type).
230+
- Added new Materialized Data Configuration value MaterializedDataLoadingTableDataCopyMode to control whether the materialized data process automatically copies data into the Loading Tables after cloning.
231+
This helps to greatly simplify new use cases where data must be merged (and preserved) during the materialization process.
232+
218233
## v2.3.1 Release Notes:
219234
- Fixed bug with Sql Bulk Insert/Update processing with Model Properties that have mapped database names via mapping attribute (e.g. [SqlBulkColumn("")], [Map("")], [Column("")], etc.).
220235

SqlBulkHelpers.Tests/IntegrationTests/MaterializeDataTests/CloneTablesTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ public async Task TestCloneTableStructureByAnnotationAsync()
2121
{
2222
var cloneInfo = await sqlTrans.CloneTableAsync<TestElementWithMappedNames>().ConfigureAwait(false);
2323

24-
var sourceTableSchema = sqlTrans.GetTableSchemaDefinition(cloneInfo.SourceTable.FullyQualifiedTableName);
25-
var clonedTableSchema = sqlTrans.GetTableSchemaDefinition(cloneInfo.TargetTable.FullyQualifiedTableName);
24+
var sourceTableSchema = await sqlTrans.GetTableSchemaDefinitionAsync(cloneInfo.SourceTable.FullyQualifiedTableName).ConfigureAwait(false);
25+
var clonedTableSchema = await sqlTrans.GetTableSchemaDefinitionAsync(cloneInfo.TargetTable.FullyQualifiedTableName).ConfigureAwait(false);
2626

2727
await sqlTrans.RollbackAsync().ConfigureAwait(false);
2828
//await sqlTransaction.CommitAsync().ConfigureAwait(false);

0 commit comments

Comments
 (0)