private void ResolvePrimaryKeyConflicts(IDataLoadEventListener job) { using (var con = (SqlConnection)_dbInfo.Server.GetConnection()) { con.Open(); PrimaryKeyCollisionResolver resolver = new PrimaryKeyCollisionResolver(TargetTable); SqlCommand cmdAreTherePrimaryKeyCollisions = new SqlCommand(resolver.GenerateCollisionDetectionSQL(), con); cmdAreTherePrimaryKeyCollisions.CommandTimeout = 5000; //if there are no primary key collisions if (cmdAreTherePrimaryKeyCollisions.ExecuteScalar().ToString().Equals("0")) { job.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "No primary key collisions detected")); return; } //there are primary key collisions so resolve them job.OnNotify(this, new NotifyEventArgs(ProgressEventType.Warning, "Primary key collisions detected")); SqlCommand cmdResolve = new SqlCommand(resolver.GenerateSQL(), con); cmdResolve.CommandTimeout = 5000; int affectedRows = cmdResolve.ExecuteNonQuery(); job.OnNotify(this, new NotifyEventArgs(ProgressEventType.Warning, "Primary key collisions resolved by deleting " + affectedRows + " rows")); con.Close(); } }
public void Check(ICheckNotifier notifier) { if (TargetTable == null) { notifier.OnCheckPerformed(new CheckEventArgs( "Target table is null, a table must be specified upon which to resolve primary key duplication (that TableInfo must have a primary key collision resolution order)", CheckResult.Fail, null)); } try { PrimaryKeyCollisionResolver resolver = new PrimaryKeyCollisionResolver(TargetTable); string sql = resolver.GenerateSQL(); } catch (Exception e) { notifier.OnCheckPerformed(new CheckEventArgs("Failed to check PrimaryKeyCollisionResolver on " + TargetTable, CheckResult.Fail, e)); } }
public void NoPrimaryKeys_ThrowsException() { TableInfo t; ColumnInfo c1; ColumnInfo c2; ColumnInfo c3; SetupTableInfos(out t, out c1, out c2, out c3); try { PrimaryKeyCollisionResolver resolver = new PrimaryKeyCollisionResolver(t); var ex = Assert.Throws <Exception>(() => Console.WriteLine(resolver.GenerateSQL())); StringAssert.Contains("does not have any primary keys defined so cannot resolve primary key collisions", ex.Message); } finally { t.DeleteInDatabase(); } }
public void GenerateSQL_OrderCorrect() { TableInfo t; ColumnInfo c1; ColumnInfo c2; ColumnInfo c3; SetupTableInfos(out t, out c1, out c2, out c3); try { c1.IsPrimaryKey = true; c1.SaveToDatabase(); c2.DuplicateRecordResolutionOrder = 1; c2.DuplicateRecordResolutionIsAscending = true; c2.SaveToDatabase(); c3.DuplicateRecordResolutionOrder = 2; c3.DuplicateRecordResolutionIsAscending = false; c3.SaveToDatabase(); PrimaryKeyCollisionResolver resolver = new PrimaryKeyCollisionResolver(t); string sql = resolver.GenerateSQL(); Console.WriteLine(sql); Assert.IsTrue(sql.Contains(c2.Name)); Assert.IsTrue(sql.Contains(c3.Name)); //column 2 has the following null substitute, is Ascending order and is the first of two Assert.IsTrue(sql.Contains("ISNULL([col2],-9223372036854775808) ASC,")); //column 3 has the following null substitute and is descending and is not followed by another column Assert.IsTrue(sql.Contains("ISNULL([col3],-2147483648) DESC")); } finally { t.DeleteInDatabase(); } }
public void NoColumnOrdersConfigured_ThrowsException() { TableInfo t; ColumnInfo c1; ColumnInfo c2; ColumnInfo c3; SetupTableInfos(out t, out c1, out c2, out c3); try { c1.IsPrimaryKey = true; c1.SaveToDatabase(); PrimaryKeyCollisionResolver resolver = new PrimaryKeyCollisionResolver(t); var ex = Assert.Throws <Exception>(() => Console.WriteLine(resolver.GenerateSQL())); StringAssert.Contains("The ColumnInfos of TableInfo PrimaryKeyCollisionResolverTests do not have primary key resolution orders configured (do not know which order to use non primary key column values in to resolve collisions). Fix this by right clicking a TableInfo in CatalogueManager and selecting 'Configure Primary Key Collision Resolution'.", ex.Message); } finally { t.DeleteInDatabase(); } }
private void RefreshUIFromDatabase() { lbPrimaryKeys.Items.Clear(); lbConflictResolutionColumns.Items.Clear(); foreach (var pkCol in _table.ColumnInfos.Where(col => col.IsPrimaryKey)) { //primary keys are not used to resolve duplication of primary key values (obviously!) if (pkCol.DuplicateRecordResolutionOrder != null) { //unset any that have accidentally gained an order e.g. if user set an order then made a new column a PK pkCol.DuplicateRecordResolutionOrder = null; pkCol.SaveToDatabase(); } lbPrimaryKeys.Items.Add(pkCol); } List <IResolveDuplication> resolvers = new List <IResolveDuplication>(); resolvers.AddRange(_table.ColumnInfos.Where(col => !col.IsPrimaryKey)); resolvers.AddRange(_table.PreLoadDiscardedColumns); //if there is no order yet if (resolvers.All(r => r.DuplicateRecordResolutionOrder == null)) { for (int i = 0; i < resolvers.Count; i++) { //set one up resolvers[i].DuplicateRecordResolutionOrder = i; resolvers[i].SaveToDatabase(); } } foreach (IResolveDuplication resolver in resolvers.OrderBy(o => o.DuplicateRecordResolutionOrder).ToArray()) { //if it starts with hic_ if (SpecialFieldNames.IsHicPrefixed(resolver)) { //do not use it for duplication resolution resolver.DuplicateRecordResolutionOrder = null; resolver.DuplicateRecordResolutionIsAscending = false; //default to descending resolver.SaveToDatabase(); resolvers.Remove(resolver); } } foreach (IResolveDuplication resolver in resolvers.OrderBy(c => c.DuplicateRecordResolutionOrder)) { lbConflictResolutionColumns.Items.Add(resolver); } QueryEditor.ReadOnly = false; try { //this is used only to generate the SQL preview of how to resolve primary key collisions so no username/password is required - hence the null,null PrimaryKeyCollisionResolver resolver = new PrimaryKeyCollisionResolver(_table); QueryEditor.Text = resolver.GenerateSQL(); CommonFunctionality.ScintillaGoRed(QueryEditor, false); } catch (Exception e) { CommonFunctionality.ScintillaGoRed(QueryEditor, e); } QueryEditor.ReadOnly = true; }