Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

improving error messaging and exception handling

  • Loading branch information...
commit 24a6b6c56343d3bc97e6d3837b68f5b2540f0c71 1 parent b817eea
@ssandler ssandler authored
View
25 TeslaSQL/Agents/Slave.cs
@@ -376,11 +376,26 @@ public Slave(IDataUtils sourceDataUtils, IDataUtils destDataUtils, Logger logger
//tableCTName.Keys instead of tables because we've already filtered this for tables that don't have change tables
//note: allColumnsByTable.Keys or primaryKeysByTable.Keys should work just as well
- foreach (var table in tableCTName.Keys) {
- //this is a hacky solution but we will have these columns in CT tables but actually are not interested in them here.
- var columns = allColumnsByTable[table].Where(c => (c.name != "SYS_CHANGE_VERSION" && c.name != "SYS_CHANGE_OPERATION"));
-
- var pks = primaryKeysByTable[table];
+ foreach (var table in tableCTName.Keys) {
+ IEnumerable<TColumn> columns;
+ try {
+ //this is a hacky solution but we will have these columns in CT tables but actually are not interested in them here.
+ columns = allColumnsByTable[table].Where(c => (c.name != "SYS_CHANGE_VERSION" && c.name != "SYS_CHANGE_OPERATION"));
+ } catch (KeyNotFoundException) {
+ var e = new Exception("Column list for table " + tableCTName[table] + " not found in " + dbName);
+ HandleException(e, table);
+ //if we handled the exception by just logging an error, this table is still broken so we need to continue
+ continue;
+ }
+ IList<string> pks;
+ try {
+ pks = primaryKeysByTable[table];
+ } catch (KeyNotFoundException) {
+ var e = new Exception("Primary keys for table " + table.FullName + " not found in " + dbName + ".dbo.tblCTTableInfo_" + batch.CTID);
+ HandleException(e, table);
+ //if we handled the exception by just logging an error, this table is still broken so we need to continue
+ continue;
+ }
foreach (var pk in pks) {
columns.First((c => c.name == pk)).isPk = true;
}
View
6 TeslaSQL/DataType.cs
@@ -43,6 +43,12 @@ public class DataType {
}
public static string MapDataType(SqlFlavor source, SqlFlavor dest, string datatype) {
datatype = datatype.ToLower();
+ if (dataMappings.Count == 0) {
+ throw new Exception("Data mappings file not loaded, unable to map data types! Please specify a data mappings file using the -p argument of Tesla.");
+ }
+ if (!dataMappings.ContainsKey(source) || !dataMappings.ContainsKey(dest)) {
+ throw new Exception("The data mappings file seems to be incorrect, please specify a data type mappings file that maps from " + source + " to " + dest);
+ }
int idx = dataMappings[source].IndexOf(datatype);
if (idx == -1) {
return datatype;
View
36 TeslaSQL/DataUtils/MSSQLDataUtils.cs
@@ -64,7 +64,14 @@ public class MSSQLDataUtils : IDataUtils {
private T SqlQueryToScalar<T>(string dbName, SqlCommand cmd, int? timeout = null) {
DataTable result = SqlQuery(dbName, cmd, timeout);
//return result in first column and first row as specified type
- return (T)result.Rows[0][0];
+ T toRet;
+ try {
+ toRet = (T)result.Rows[0][0];
+ } catch (InvalidCastException) {
+ throw new Exception("Unable to cast value " + result.Rows[0][0].ToString() + " to type " + typeof(T) +
+ " when running query: " + ParseCommand(cmd));
+ }
+ return toRet;
}
/// <summary>
@@ -100,13 +107,20 @@ public class MSSQLDataUtils : IDataUtils {
/// </summary>
/// <param name="cmd">SqlCommand to be run</param>
private void LogCommand(SqlCommand cmd) {
+ logger.Log("Executing query: " + ParseCommand(cmd), LogLevel.Debug);
+ }
+
+ /// <summary>
+ /// Parse a SQL query, substituting parameters for their values.
+ /// </summary>
+ private string ParseCommand(SqlCommand cmd) {
string query = cmd.CommandText;
foreach (SqlParameter p in cmd.Parameters) {
query = query.Replace(p.ParameterName, "'" + p.Value.ToString() + "'");
}
- logger.Log("Executing query: " + query, LogLevel.Debug);
+ return query;
}
@@ -203,7 +217,7 @@ public class MSSQLDataUtils : IDataUtils {
public Int64 GetMinValidVersion(string dbName, string table, string schema) {
- SqlCommand cmd = new SqlCommand("SELECT CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID(@tablename))");
+ SqlCommand cmd = new SqlCommand("SELECT ISNULL(CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID(@tablename)), 0)");
cmd.Parameters.Add("@tablename", SqlDbType.VarChar, 500).Value = schema + "." + table;
return SqlQueryToScalar<Int64>(dbName, cmd);
}
@@ -1212,5 +1226,21 @@ THEN DELETE
return SqlQuery(dbName, cmd);
}
+ public void MergeInfoTable(string shardDB, string consolidatedDB, long CTID) {
+ //merge rows into the consolidated info table. this is used for sharded agents.
+ //the shardcoordinator will only publish the rows for tables that actually had changes
+ //but then we pull in the others so that slaves get the PK list, which ends up getting used
+ //for consolidated batches on the slaves.
+ string sql = string.Format(@"INSERT INTO [dbo].[tblCTtableInfo_{1}] (CtiTableName, CtiSchemaName, CtiPKList, CtiExpectedRows, CtiInsertCount)
+ SELECT CtiTableName, CtiSchemaName, CtiPKList, CtiExpectedRows, CtiInsertCount
+ FROM [{0}].[dbo].[tblCTtableInfo_{1}] i
+ WHERE NOT EXISTS
+ (SELECT 1 FROM [dbo].[tblCTtableInfo_{1}]
+ WHERE CtiTableName = i.CtiTableName AND CtiSchemaName = i.CtiSchemaName)",
+ shardDB, CTID);
+ var cmd = new SqlCommand(sql);
+ SqlNonQuery(consolidatedDB, cmd);
+ }
+
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.