/// <summary> /// Parses command-line arguments into a reference-type object. Displays /// usage message to Console.Out if invalid arguments are encountered. /// Errors are output on Console.Error. Use ArgumentAttributes to /// control parsing behavior. /// </summary> /// <typeparam name="T">Type of the parsed arguments object.</typeparam> /// <param name="arguments">The actual arguments.</param> /// <param name="destination">The resulting parsed arguments.</param> /// <param name="reporter">The destination for parse errors.</param> /// <returns>True if no errors were detected.</returns> public static bool ParseWithUsage <T>(IEnumerable <string> arguments, T destination, ErrorReporter reporter) where T : class => ParseWithUsage(arguments, destination, new CommandLineParserOptions { Reporter = s => reporter?.Invoke(s.ToString()) });
public void Run(ProgressReporter progressReporter = null, ErrorReporter errorReporter = null) { if (false == File.Exists(Config.BigSqlFilePath)) { 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 = GetSessionLevelDbPath(Config.BigSqlFilePath); if (false == Config.ContinueFromLastSessionWhenStarted && Directory.Exists(sessionLevelDbPath)) { var sessionBackupPath = GetSessionBackupPath(sessionLevelDbPath); Directory.Move(sessionLevelDbPath, sessionBackupPath); } using (var streamReader = new StreamReader(Config.BigSqlFilePath)) using (var sessionDb = new SessionLevelDb(sessionLevelDbPath, Config.SessionSaveType)) { int sqlUnitIndex = 0; int affectedRows = 0; while (true) { // stop when requested if (Stop) { StopCallBack?.Invoke(); return; } // read from file var sqlUnitList = ReadBatchSqlUnits(streamReader, Config.BatchSize, Config.SqlUnitEndingLine, sessionDb, ref sqlUnitIndex); if (false == sqlUnitList.Any()) { break; } // prepare sql var batchSql = SqlUnit.CombineSqlUnitList(sqlUnitList); if (false == string.IsNullOrWhiteSpace(batchSql)) { // batch execute sql HelperFns.TryThenException( () => { var thisAffectedRows = RunSql(Config.ConnectionString, batchSql); if (thisAffectedRows > 0) { affectedRows += thisAffectedRows; } }, Config.RetryIntervalWhenError, true, Config.RetryNumberWhenError + 1, (e, i) => errorReporter?.Invoke($"{e.Message}; retry in {Config.RetryIntervalWhenError.TotalSeconds} seconds...") ); // set executing status foreach (var sqlUnit in sqlUnitList) { sessionDb.SetSqlUnitExecuteStatus(sqlUnit.Index, sqlUnit.Sql, true); } // report progress progressReporter?.Invoke(sqlUnitIndex, affectedRows); } } } }
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; } }