/// <summary> /// This method attempts to order a list of script files for batch-execution under /// ACID transaction mode. /// <para> /// It performs this by running a list of scripts under transcation (ACID) mode. /// If one of the script fail to process successfully (due to missing requirements /// or other erroneous reason), it is moved to the end of the list. And the test /// is re-run with the new order. /// </para> /// <para> /// The loop continues each time with a different order until the order is /// fully exhausted. Upon completion, it returns the pivotalIndex int value. /// </para> /// <para> /// The pivotalIndex value marks the starting/ending spot to divide the list of /// scripts of usable/unusable scripts. /// </para> /// <para> /// If all scripts ran successfully, the pivotalIndex is equal to the total number /// of scripts passed (ie: the array's length). If pivotalIndex is equals to 0, /// all of the scripts failed, apparently. /// </para> /// <para> /// For example, if you have 10 filename and the pivotalIndex is 6, it means the /// filenames[0 thru 5] were successful and the filenames[6 thru 9] were error. /// </para> /// </summary> /// <param name="filenames"></param> /// <param name="successList"></param> /// <param name="failList"></param> /// <param name="logfile"></param> /// <returns></returns> public int ExecuteFileTranSmart( string[] filenames, out string[] successList, out string[] failList, string logfile ) { List <String> fileList = new List <string>(); List <String> buffList = new List <string>(); for (int i = 0; i < filenames.Length; i++) { fileList.Add(filenames[i]); buffList.Add(StringUtil.StringArrayToString(FileUtil.ReadFile(filenames[i]))); } // delete log file File.Delete(logfile); int max = filenames.Length; int loopCounter = 0; int lastErrorIndex = -1; int pivotalIndex = 0; while (loopCounter < max) { try { ExecuteBufferTran(buffList.ToArray(), null, ExecuteTypes.ExecuteNonQuery); pivotalIndex = buffList.Count; break; } catch (Exception ex) { #region The Smart Algorithm try { if ((ex.Data.Contains("index")) && (int.TryParse(ex.Data["index"].ToString(), out pivotalIndex))) { string tempFile = fileList[pivotalIndex]; string tempBuff = buffList[pivotalIndex]; fileList.RemoveAt(pivotalIndex); buffList.RemoveAt(pivotalIndex); fileList.Add(tempFile); buffList.Add(tempBuff); // check for infinite loop ... if (pivotalIndex == lastErrorIndex) { loopCounter++; } else { lastErrorIndex = pivotalIndex; loopCounter = pivotalIndex; } #region Logging to File try { StringBuilder sfoo = new StringBuilder(); Exception exfoo = ex; sfoo.AppendFormat("moving to end of list: {1} | {2} | {3} | {4}{0}", Environment.NewLine, pivotalIndex, loopCounter, max, tempFile); while (exfoo != null) { sfoo.AppendFormat("Message: {1}{0}", Environment.NewLine, exfoo.Message); exfoo = exfoo.InnerException; } // move idx to the end of the list. FileUtil.AppendFile(logfile, sfoo.ToString()); } catch (Exception ex3) { throw new ApplicationException("Error logging", ex3); } #endregion continue; } } catch (Exception ex2) { throw new ApplicationException("Error in the Smart Algorithm", ex2); } #endregion } } // create successList and failList if (pivotalIndex > 0) { successList = StringUtil.CopyList(fileList, 0, pivotalIndex - 1); } else { successList = new string[0]; } failList = StringUtil.CopyList(fileList, pivotalIndex, fileList.Count - 1); return(pivotalIndex); }