public void Import(Window parentWindow, ImportWizardContext context, IProgressObserver progress, Action <ImportStatusLevel, string> logFunc) { this.ParentWindow = parentWindow; this.Importer = context.Importer; this.Mappings = context.FieldMappings; this.Progress = progress; this.LogFunc = logFunc; if (Progress != null) { Progress.ProgressStart("Initialising..."); } if (!InitImport()) { return; } ProgressMsg("Importing data - Stage 1", 0); if (!DoStage1()) { return; } CreateColumnIndexes(); Cancelled = false; var connection = User.GetConnection(); LogMsg("Importing data - Stage 2", 10); int rowCount = 0; int lastPercent = 0; DateTime timeStarted = DateTime.Now; DateTime lastCheck = timeStarted; RowSource.Reset(); while (RowSource.MoveNext() && !Cancelled) { ImportCurrentRow(rowCount++, connection); var dblPercent = (double)((double)rowCount / (double)RowSource.RowCount) * 90; int percent = ((int)dblPercent) + 10; var timeSinceLastUpdate = DateTime.Now - lastCheck; if (percent != lastPercent || timeSinceLastUpdate.Seconds > 5) { var timeSinceStart = DateTime.Now - timeStarted; var avgMillisPerRow = (double)(timeSinceStart.TotalMilliseconds == 0 ? 1 : timeSinceStart.TotalMilliseconds) / (double)(rowCount == 0 ? 1 : rowCount); var rowsLeft = RowSource.RowCount - rowCount; var secondsLeft = (int)((double)(rowsLeft * avgMillisPerRow) / 1000.0); lastCheck = DateTime.Now; TimeSpan ts = new TimeSpan(0, 0, secondsLeft); var message = string.Format("Importing rows - Stage 2 ({0} of {1}). {2} remaining.", rowCount, RowSource.RowCount, ts.ToString()); ProgressMsg(message, percent); lastPercent = percent; } } ProgressMsg("Importing rows - Stage 2 Complete", 100); LogMsg("{0} Rows successfully imported, {1} rows failed with errors", _successCount, _errorCount); LogMsg("Cleaning up staging database..."); if (RowSource.Service.GetErrorCount() > 0) { if (ParentWindow.Question("Errors were encountered during the import. Rejected rows can be corrected and re-imported by re-running the import wizard and selecting the 'Import Error Database' option. Would you like to save the rejected rows so that they can be corrected and re-imported?", "Save rejected rows?", System.Windows.MessageBoxImage.Exclamation)) { // Clean out just the imported records, leaving just the error rows... LogMsg("Purging successfully imported rows from staging database..."); RowSource.Service.PurgeImportedRecords(); LogMsg("Saving mapping information to staging database..."); RowSource.Service.SaveMappingInfo(Importer, Mappings); LogMsg("Disconnecting from staging database..."); RowSource.Service.Disconnect(); var dlg = new Microsoft.Win32.SaveFileDialog(); dlg.Filter = "SQLite database files|*.sqlite|All files (*.*)|*.*"; dlg.Title = "Save error database file"; if (dlg.ShowDialog().ValueOrFalse()) { LogMsg("Copying staging database from {0} to {1}", RowSource.Service.FileName, dlg.FileName); System.IO.File.Copy(RowSource.Service.FileName, dlg.FileName, true); } } } connection.Close(); }