public async Task Run(ProgressReporter progressReporter = null, ErrorReporter errorReporter = null) { try { WriteLog += WriteLogToFile; await LogPool.AddLog(LogItem.MakeLog(new LogMessage(">> Started running..."))); var bigSqlStorageFile = await StorageFile.GetFileFromPathAsync(Config.BigSqlFilePath); if (null == bigSqlStorageFile) { throw new ArgumentException($"specified big sql file not exist: {Config.BigSqlFilePath}", nameof(Config.BigSqlFilePath)); } // reset the stop flag if (Stop) { return; } Stop = false; var sessionLevelDbPath = await GetSessionLevelDbPath(Config.BigSqlFilePath); if (false == Config.ContinueFromLastSessionWhenStarted && Directory.Exists(sessionLevelDbPath)) { var sessionBackupPath = GetSessionBackupPath(sessionLevelDbPath); Directory.Move(sessionLevelDbPath, sessionBackupPath); } using (var readStream = await bigSqlStorageFile.OpenStreamForReadAsync()) using (var streamReader = new StreamReader(readStream)) using (var sessionDb = new SessionLevelDb(sessionLevelDbPath, Config.SessionSaveType)) { int sqlUnitIndex = 0; int affectedRows = 0; while (true) { // stop when requested if (Stop) { await LogPool.AddLog(LogItem.MakeLog(new LogMessage(">> Canceled by user."))); StopCallBack?.Invoke(); return; } // read from file var startUnitIndex = sqlUnitIndex; var sqlUnitList = ReadBatchSqlUnits(streamReader, Config.BatchSize, Config.SqlUnitEndingLine, sessionDb, ref sqlUnitIndex); // check skip count var unitIndexDiff = sqlUnitIndex - startUnitIndex; var skipCount = unitIndexDiff - sqlUnitList.Count(); if (skipCount > 0) { await LogPool.AddLog(LogItem.MakeLog(new LogMessage($"Skipped {skipCount} already executed units."))); } // break when nothing to do if (false == sqlUnitList.Any()) { break; } // prepare sql var batchSql = SqlUnit.CombineSqlUnitList(sqlUnitList); if (false == string.IsNullOrWhiteSpace(batchSql)) { // batch execute sql await HelperFns.TryThenException( async() => { var thisAffectedRows = await RunSql(Config.ConnectionString, batchSql); if (thisAffectedRows > 0) { affectedRows += thisAffectedRows; } }, Config.RetryIntervalWhenError, true, Config.RetryNumberWhenError + 1, async (e, i) => { var message = $"{e.Message}; retry in {Config.RetryIntervalWhenError.TotalSeconds} seconds..."; await LogPool.AddLog(LogItem.MakeLog(new LogMessage(message))); errorReporter?.Invoke(message); } ); // set executing status foreach (var sqlUnit in sqlUnitList) { sessionDb.SetSqlUnitExecuteStatus(sqlUnit.Index, sqlUnit.Sql, true); } // report progress await LogPool.AddLog(LogItem.MakeLog(new LogMessage(sqlUnitIndex, affectedRows))); progressReporter?.Invoke(sqlUnitIndex, affectedRows); } } } await LogPool.AddLog(LogItem.MakeLog(new LogMessage(">> Completed."))); } finally { WriteLog -= WriteLogToFile; } }
public IEnumerable <SqlUnit> ReadBatchSqlUnits(TextReader textReader, int batchSize, string sqlUnitEndingLine, SessionLevelDb sessionDb, ref int sqlUnitIndex) { var unitList = new List <SqlUnit>(); for (int i = 0; i < batchSize;) { var thisUnit = ReadSqlUnit(textReader, sqlUnitEndingLine); if (null == thisUnit) { break; } var unit = new SqlUnit(sqlUnitIndex++, thisUnit); if (sessionDb.IsSqlUnitAlreadyExecuted(unit.Index, unit.Sql)) { continue; } unitList.Add(unit); i++; } return(unitList); }