Ejemplo n.º 1
0
        public void TestNestedKill()
        {
            var lines    = new SyncCollection();
            var pipeline = TestShell.Run(SampleCommand, "pipe")
                           | TestShell.Run(SampleCommand, "pipe")
                           | TestShell.Run(SampleCommand, "pipe") > lines;

            // demonstrate that a single line can make it all the way through the pipeline
            // without getting caught in a buffer along the way
            pipeline.StandardInput.AutoFlush.ShouldEqual(true);
            pipeline.StandardInput.WriteLine("a line");
            var start = DateTime.UtcNow;

            while ((DateTime.UtcNow - start) < TimeSpan.FromSeconds(10))
            {
                if (lines.Count > 0)
                {
                    break;
                }
                Thread.Sleep(10);
            }
            pipeline.Task.IsCompleted.ShouldEqual(false);
            lines.FirstOrDefault().ShouldEqual("a line");

            pipeline.Task.IsCompleted.ShouldEqual(false);
            pipeline.Kill();
            pipeline.Result.Success.ShouldEqual(false);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// handels the sync button click event
        /// </summary>
        /// <param name="sender">
        /// The sender of this event.
        /// </param>
        /// <param name="e">
        /// The empty event args for event handling system.
        /// </param>
        private void ButtonSyncWithXing_Click(object sender, EventArgs e)
        {
            // using a lambda here is much less code
            EventHandler <ProgressEventArgs> progress = (s, evnt) => this.progressBar.Value = evnt.PercentageDone;

            // first attach to the events to update the progress bar and the
            // log list for the user.
            this.engine.ProcessingEvent += this.LogThis;
            this.engine.ProgressEvent   += progress;

            // load a SyncCollection from the xml file (this can be
            // modified in order to change behavior)
            var list = SyncCollection.LoadSyncList("commands.xml");

            // now execute the list of commands
            this.engine.Execute(list);

            // detach from the events - there's nothing we should get from there
            // any more.
            this.engine.ProcessingEvent -= this.LogThis;
            this.engine.ProgressEvent   -= progress;

            // tell the user we have finished
            MessageBox.Show(Resources.messageFinished, this.Text);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// execute the commands stored inside the list
        /// </summary>
        /// <param name="syncList"> the list to execute </param>
        /// <returns> a value specifying if the execution should continue </returns>
        public bool Execute(SyncCollection syncList)
        {
            var itemsDone = 0;

            this.numberOfCommandsInSequence = syncList.Count;

            LogProcessingEvent(string.Format(CultureInfo.CurrentCulture, Resources.uiStartingProcessing, this.percentageOfSequenceDone));

            foreach (var item in syncList)
            {
                this.percentageOfSequenceDone = itemsDone * 100 / this.numberOfCommandsInSequence;
                UpdateProgress(this.percentageOfSequenceDone);
                if (!this.Execute(item))
                {
                    LogProcessingEvent(Resources.uiProcessingCanceled);
                    UpdateProgress(0);
                    return(false);
                }

                itemsDone++;
            }

            UpdateProgress(100);
            return(true);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Runs the currently selected template with the currently loaded data.
        /// </summary>
        /// <param name="templateScriptPath">
        /// The path to the template script.
        /// </param>
        public void Run(string templateScriptPath)
        {
            if (!File.Exists(templateScriptPath))
            {
                this.ProcessingEvent(this, new ProcessingEventArgs(string.Format(CultureInfo.CurrentCulture, Resources.InstalledFileNotFound, templateScriptPath)));
                return;
            }

            var commands = SyncCollection.LoadSyncList(templateScriptPath);

            if (commands == null)
            {
                return;
            }

            foreach (var command in commands)
            {
                command.SourceCredentials = (command.SourceConnector != null && command.SourceConnector == "{source}") ? this.Source.LogonCredentials : command.SourceCredentials;
                command.SourceCredentials = (command.SourceConnector != null && command.SourceConnector == "{target}") ? this.Target.LogonCredentials : command.SourceCredentials;
                command.TargetCredentials = (command.TargetConnector != null && command.TargetConnector == "{source}") ? this.Source.LogonCredentials : command.TargetCredentials;
                command.TargetCredentials = (command.TargetConnector != null && command.TargetConnector == "{target}") ? this.Target.LogonCredentials : command.TargetCredentials;

                command.SourceConnector  = this.ReplaceToken(command.SourceConnector);
                command.TargetConnector  = this.ReplaceToken(command.TargetConnector);
                command.SourceStorePath  = this.ReplaceToken(command.SourceStorePath);
                command.TargetStorePath  = this.ReplaceToken(command.TargetStorePath);
                command.CommandParameter = this.ReplaceToken(command.CommandParameter);
            }

            var engine = new SyncEngine
            {
                WorkingFolder = Config.WorkingFolder,
                UiProvider    = new UiDispatcher(),
            };

            engine.ProcessingEvent += this.HandleProcessingEvent;
            engine.ProgressEvent   += this.ProgressEvent;

            try
            {
                engine.Execute(commands);
            }
            catch (ProcessAbortException)
            {
            }

            engine.ProcessingEvent -= this.HandleProcessingEvent;
            engine.ProgressEvent   -= this.ProgressEvent;

            if (this.FinishedEvent != null)
            {
                this.FinishedEvent(new ProgressEventArgs {
                    PercentageDone = 100
                });
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// performs the setup of the form after loading the controls
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The empty event arguments.
        /// </param>
        private void LocalSync_Load(object sender, EventArgs e)
        {
            // todo: this should be handled by the viewmodel instead of the code behind

            // route the events
            this.DataContext.ProcessingEvent += this.LogMessage;
            this.DataContext.ProgressEvent   += this.OnProgressEvent;

            // we can use a lambda, because we will never need to detach
            this.DataContext.QueryForLogOnCredentials += (s, eargs) => new LogOn().SetLogonCredentials((IClientBase)s, eargs);

            // get the data for the combo box from the file system paths
            this.SyncListSelection.DataSource =
                (from x in Directory.GetFiles(SyncWizardContext.WorkingFolderTemplates, "*.SyncList")
                 select new { Name = Path.GetFileName(x), Path = x }).ToList();

            // display file name only, but store full path
            this.SyncListSelection.ValueMember   = "Path";
            this.SyncListSelection.DisplayMember = "Name";

            // add event handler that will use the >>value<< instead of the text
            // to load the grid
            this.SyncListSelection.SelectedValueChanged += (cbs, cbe) =>
            {
                var item = ((ComboBox)cbs).SelectedValue;
                if (item != null)
                {
                    this.DataContext.SyncCommands = SyncCollection.LoadSyncList(item.ToString());
                }

                this.syncListBindingSource.DataSource = this.DataContext.SyncCommands;
            };

            // unselect first entry, then select one, if there is one ;-) - this will fire the SelectedValueChanged
            this.SyncListSelection.SelectedIndex = -1;
            if (this.SyncListSelection.Items.Count > 0)
            {
                this.SyncListSelection.SelectedIndex = 0;
            }

            this.dataGridView1.KeyDown += (kps, kpe) =>
            {
                if (kpe.KeyCode == Keys.Enter)
                {
                    this.RunSelectedRow();
                }
            };

            this.dataGridView1.CellDoubleClick += (gvs, gve) => this.RunRowCommand(gve.RowIndex);

            // setup the commands
            this.openWorkingFolderToolStripMenuItem.Click += (s, ev) => this.DataContext.OpenWorkingFolder();
            this.exitToolStripMenuItem.Click += (s, ev) => this.Close();
            this.runSelected.Click           += (s, ev) => this.RunSelectedRow();
        }
Ejemplo n.º 6
0
 private static void ParseSyncKey(SyncCollection collection)
 {
     collection.AllowRecovery = collection.ParseSynckeyAndDetermineRecovery();
     if (collection.SyncKey == 0U)
     {
         collection.Status = SyncBase.ErrorCodeStatus.UnprimedSyncState;
         throw new AirSyncPermanentException(false)
               {
                   ErrorStringForProtocolLogger = "SyncNotPrimed"
               };
     }
 }
Ejemplo n.º 7
0
 public void TestCancellationCanceledPartway()
 {
     using (var cancellationTokenSource = new CancellationTokenSource())
     {
         var results = new SyncCollection();
         var command = TestShell.Run(SampleCommand, new object[] { "echo", "--per-char" }, o => o.CancellationToken(cancellationTokenSource.Token)) > results;
         command.StandardInput.WriteLine("hello");
         var timeout = Task.Delay(TimeSpan.FromSeconds(10));
         while (results.Count == 0 && !timeout.IsCompleted)
         {
         }
         results.Count.ShouldEqual(1);
         cancellationTokenSource.Cancel();
         var aggregateException = Assert.Throws <AggregateException>(() => command.Task.Wait(1000));
         Assert.IsInstanceOf <TaskCanceledException>(aggregateException.GetBaseException());
         CollectionAssert.AreEqual(results, new[] { "hello" });
     }
 }
Ejemplo n.º 8
0
        private void FinalizeResponseNode(SyncCollection collection)
        {
            AirSyncDiagnostics.TraceInfo(ExTraceGlobals.RequestsTracer, this, "GIE.FinalizeResponseNode");
            XmlElement xmlElement = base.XmlResponse.CreateElement("Response", "GetItemEstimate:");

            this.getItemEstimateXmlNode.AppendChild(xmlElement);
            XmlElement xmlElement2 = base.XmlResponse.CreateElement("Status", "GetItemEstimate:");

            xmlElement2.InnerText = this.GetStatusString(collection.Status);
            base.ProtocolLogger.SetValue(collection.InternalName, PerFolderProtocolLoggerData.PerFolderStatus, (int)collection.Status);
            XmlElement xmlElement3 = base.XmlResponse.CreateElement("Collection", "GetItemEstimate:");
            XmlElement xmlElement4 = base.XmlResponse.CreateElement("Class", "GetItemEstimate:");

            xmlElement4.InnerText = collection.ClassType;
            XmlElement xmlElement5 = base.XmlResponse.CreateElement("CollectionId", "GetItemEstimate:");

            xmlElement5.InnerText = collection.CollectionId;
            if (base.Version < 121)
            {
                xmlElement3.AppendChild(xmlElement4);
            }
            if (collection.ReturnCollectionId)
            {
                xmlElement3.AppendChild(xmlElement5);
            }
            if (collection.Status == SyncBase.ErrorCodeStatus.Success)
            {
                XmlElement xmlElement6 = base.XmlResponse.CreateElement("Estimate", "GetItemEstimate:");
                xmlElement6.InnerText = collection.ServerChanges.Count.ToString(CultureInfo.InvariantCulture);
                xmlElement3.AppendChild(xmlElement6);
            }
            base.ProtocolLogger.IncrementValue(ProtocolLoggerData.TotalFolders);
            xmlElement.AppendChild(xmlElement2);
            xmlElement.AppendChild(xmlElement3);
            this.getItemEstimateXmlNode.AppendChild(xmlElement);
        }
Ejemplo n.º 9
0
        public void GetChanges(SyncCollection collection, bool autoLoadFilterAndSyncKey, bool tryNullSync, bool commitSyncState, bool enumerateAllchanges)
        {
            AirSyncDiagnostics.TraceInfo <bool, bool, bool>(ExTraceGlobals.RequestsTracer, this, "GIE:GetChanges autoLoadFilterAndSyncKey:{0} tryNullSync:{1} commitSyncState:{2}", autoLoadFilterAndSyncKey, tryNullSync, commitSyncState);
            base.InitializeVersionFactory(base.Version);
            collection.SetDeviceSettings(this);
            long utcTicks        = ExDateTime.Now.Date.UtcTicks;
            bool nullSyncAllowed = !base.IsInQuarantinedState || base.IsQuarantineMailAvailable;

            if (tryNullSync && !collection.CollectionRequiresSync(autoLoadFilterAndSyncKey, nullSyncAllowed))
            {
                base.ProtocolLogger.SetProviderSyncType(collection.CollectionId, ProviderSyncType.N);
                collection.SetEmptyServerChanges();
                return;
            }
            collection.OpenSyncState(autoLoadFilterAndSyncKey, base.SyncStateStorage);
            if (base.Context.Request.Version < 160 && collection.FolderType == DefaultFolderType.Drafts)
            {
                AirSyncDiagnostics.TraceInfo(ExTraceGlobals.RequestsTracer, this, "[GIE.GetChanges] Ignoring request to sync drafts.");
                collection.SetEmptyServerChanges();
                return;
            }
            try
            {
                if (collection.HasOptionsNodes)
                {
                    collection.ParseSyncOptions();
                }
                else if (collection.HasFilterNode)
                {
                    collection.ParseFilterType(null);
                }
                else
                {
                    collection.ParseStickyOptions();
                }
            }
            catch (AirSyncPermanentException ex)
            {
                base.ProtocolLogger.AppendValue(ProtocolLoggerData.Error, string.Format("ParsingError:{0}", ex.ErrorStringForProtocolLogger));
                base.GlobalStatus = SyncBase.ErrorCodeStatus.ProtocolError;
                throw;
            }
            collection.AddDefaultOptions();
            collection.InitializeSchemaConverter(base.VersionFactory, base.GlobalInfo);
            bool syncProviderOptions = base.IsQuarantineMailAvailable && (base.GlobalInfo.DeviceAccessStateReason == DeviceAccessStateReason.ExternalCompliance || base.GlobalInfo.DeviceAccessStateReason == DeviceAccessStateReason.ExternalEnrollment);

            collection.SetSyncProviderOptions(syncProviderOptions);
            collection.OpenFolderSync();
            collection.VerifySyncKey(false, base.GlobalInfo);
            if (collection.CollectionId != null)
            {
                base.ProtocolLogger.SetValue(collection.InternalName, PerFolderProtocolLoggerData.FolderId, collection.CollectionId);
            }
            base.ProtocolLogger.SetValue(collection.InternalName, PerFolderProtocolLoggerData.ClientSyncKey, collection.SyncKey.ToString(CultureInfo.InvariantCulture));
            if (!base.IsInQuarantinedState || base.IsQuarantineMailAvailable)
            {
                collection.SetFolderSyncOptions(base.VersionFactory, base.IsQuarantineMailAvailable, base.GlobalInfo);
                base.GlobalWindowSize -= collection.GetServerChanges(base.GlobalWindowSize, enumerateAllchanges);
            }
            else
            {
                collection.SetEmptyServerChanges();
                AirSyncDiagnostics.TraceInfo <DeviceAccessState>(ExTraceGlobals.RequestsTracer, this, "Setting empty server changes for quarantined state. Current AccessState = {0}", base.CurrentAccessState);
            }
            if (!base.IsInQuarantinedState && tryNullSync && collection.ServerChanges.Count == 0 && commitSyncState)
            {
                collection.SyncState.CustomVersion = new int?(9);
                object[] nullSyncPropertiesToSave = collection.GetNullSyncPropertiesToSave();
                try
                {
                    if (nullSyncPropertiesToSave != null)
                    {
                        collection.SyncState.CommitState(collection.PropertiesToSaveForNullSync, nullSyncPropertiesToSave);
                    }
                    else
                    {
                        collection.SyncState.CommitState(null, null);
                    }
                    collection.UpdateSavedNullSyncPropertiesInCache(nullSyncPropertiesToSave);
                    base.ProtocolLogger.IncrementValueBy(collection.InternalName, PerFolderProtocolLoggerData.SyncStateKbCommitted, (int)collection.SyncState.GetLastCommittedSize() >> 10);
                }
                catch (StorageTransientException)
                {
                    AirSyncDiagnostics.TraceError(ExTraceGlobals.RequestsTracer, this, "Transient exception thrown while saving syncstate in GIE\r\nSkipping exception due to only being for the null sync optimization.");
                }
            }
        }
Ejemplo n.º 10
0
        private void ReadXmlRequest()
        {
            AirSyncDiagnostics.TraceInfo(ExTraceGlobals.RequestsTracer, this, "GIE.ReadXmlRequest");
            XmlNode xmlRequest = base.XmlRequest;
            XmlNode xmlNode    = xmlRequest["Collections", "GetItemEstimate:"];

            if (xmlNode.ChildNodes.Count >= GlobalSettings.MaxNumOfFolders)
            {
                AirSyncDiagnostics.TraceDebug <int>(ExTraceGlobals.RequestsTracer, this, "GIE: client specified too many folders: {0}", GlobalSettings.MaxNumOfFolders);
                throw new AirSyncPermanentException(HttpStatusCode.BadRequest, StatusCode.InvalidXML, null, false)
                      {
                          ErrorStringForProtocolLogger = "GIE.TooManyFolders"
                      };
            }
            foreach (object obj in xmlNode.ChildNodes)
            {
                XmlNode        xmlNode2       = (XmlNode)obj;
                SyncCollection syncCollection = null;
                bool           flag           = false;
                try
                {
                    if (base.Version >= 140)
                    {
                        syncCollection = SyncCollection.ParseCollection(null, xmlNode2, base.Version, base.MailboxSession);
                    }
                    else
                    {
                        XmlNode xmlNode3     = xmlNode2["CollectionId"];
                        string  collectionId = (xmlNode3 == null) ? null : xmlNode3.InnerText;
                        syncCollection = SyncCollection.CreateSyncCollection(base.MailboxSession, base.Version, collectionId);
                        foreach (object obj2 in xmlNode2.ChildNodes)
                        {
                            XmlNode xmlNode4 = (XmlNode)obj2;
                            string  localName;
                            if ((localName = xmlNode4.LocalName) != null)
                            {
                                if (!(localName == "Class"))
                                {
                                    if (localName == "SyncKey")
                                    {
                                        syncCollection.SyncKeyString = xmlNode4.InnerText;
                                        continue;
                                    }
                                    if (localName == "CollectionId")
                                    {
                                        syncCollection.CollectionId = xmlNode4.InnerText;
                                        continue;
                                    }
                                    if (localName == "FilterType")
                                    {
                                        int num;
                                        if (!int.TryParse(xmlNode4.InnerText, out num) || num > 8 || num < 0)
                                        {
                                            base.GlobalStatus = SyncBase.ErrorCodeStatus.ProtocolError;
                                            base.ProtocolLogger.SetValue(ProtocolLoggerData.Error, "InvalidFilterValue");
                                            throw new AirSyncPermanentException(false);
                                        }
                                        syncCollection.FilterType    = (AirSyncV25FilterTypes)num;
                                        syncCollection.HasFilterNode = true;
                                        continue;
                                    }
                                }
                                else
                                {
                                    string innerText = xmlNode4.InnerText;
                                    string a;
                                    if ((a = innerText) != null && (a == "Email" || a == "Calendar" || a == "Contacts" || a == "Tasks" || a == "Notes"))
                                    {
                                        syncCollection.ClassType = innerText;
                                        continue;
                                    }
                                    base.ProtocolLogger.SetValue(ProtocolLoggerData.Error, "InvalidClassType");
                                    throw new AirSyncPermanentException(HttpStatusCode.InternalServerError, StatusCode.UnexpectedItemClass, null, false);
                                }
                            }
                            base.ProtocolLogger.SetValue(ProtocolLoggerData.Error, "BadNodeInRequest");
                            throw new AirSyncPermanentException(HttpStatusCode.BadRequest, StatusCode.InvalidXML, null, false);
                        }
                    }
                    base.Collections[syncCollection.InternalName] = syncCollection;
                    flag = true;
                }
                finally
                {
                    if (syncCollection != null && !flag)
                    {
                        syncCollection.Dispose();
                        syncCollection = null;
                    }
                }
            }
        }
Ejemplo n.º 11
0
 public void GetChanges(SyncCollection collection, bool autoLoadFilterAndSyncKey, bool tryNullSync, bool commitSyncState)
 {
     this.GetChanges(collection, autoLoadFilterAndSyncKey, tryNullSync, commitSyncState, true);
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Executes the list of commands specified as a path to the file containing the serialized list in the first parameter.
        /// </summary>
        /// <param name="args">
        /// The parameter that contains the path to the list of serialized commands.
        /// </param>
        public static void Main(string[] args)
        {
#if (DEBUG)
            if (args.Length < 1)
            {
                args = new[] { @"{FS:ApplicationFolder}\A Copy OutlookCal to Xml.SyncList" };
            }
#endif

            if (args.Length >= 1)
            {
                var success = false;
                try
                {
                    var defaultBaseFolder =
                        Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "SemSyncCmd");
                    Console.WriteLine(Resources.MessageInfoWorkingFolder, defaultBaseFolder);

                    // setup the sync engine
                    var engine = new SyncEngine {
                        WorkingFolder = defaultBaseFolder, UiProvider = new UiDispatcher()
                    };

                    var filename = engine.ReplacePathToken(args[0]);

                    if (!File.Exists(filename))
                    {
                        Console.WriteLine(Resources.ErrorMessageFileNotFound + filename);
                    }
                    else
                    {
                        // load the list of commands
                        Console.WriteLine(Resources.MessageInfoLoadingList, filename);
                        var syncCommands = SyncCollection.LoadSyncList(filename);

                        // feed dispatcher with credentials if specified by the command line
                        ((UiDispatcher)engine.UiProvider).UserDomain   = args.Length > 1 ? args[1] : string.Empty;
                        ((UiDispatcher)engine.UiProvider).UserName     = args.Length > 2 ? args[2] : string.Empty;
                        ((UiDispatcher)engine.UiProvider).UserPassword = args.Length > 3 ? args[3] : string.Empty;

                        // connect to events
                        engine.ProcessingEvent += ProcessingEvent;
                        engine.ProgressEvent   += ProgressEvent;

                        // execute commands
                        success = engine.Execute(syncCommands);

                        // disconnect from events
                        engine.ProcessingEvent -= ProcessingEvent;
                        engine.ProgressEvent   -= ProgressEvent;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(Resources.MessageErrorException, ex);
                }

                Console.WriteLine(Resources.MessageInfoStatus, success ? "success" : "failed");
            }
            else
            {
                Console.WriteLine(
                    Resources.MessageInfoUsage,
                    Path.GetFileNameWithoutExtension(Assembly.GetAssembly(typeof(Program)).CodeBase));
            }

#if (DEBUG)
            // wait for user input if in debug build
            Console.WriteLine(Resources.MessageInfoCloseWithEnter);
            Console.ReadLine();
#endif
        }
        public override void Execute()
        {
            try
            {
                Dictionary <string, SyncEntity> completedImports = ReadCompletedImports();

                var allFiles = ReadFiles(FilesFilter);
                Program.Console($"Found {allFiles.Length} files to import");
                foreach (var f in allFiles.OrderBy(f => f.Name))
                {
                    if (completedImports.ContainsKey(f.Name))
                    {
                        Program.Console($"Skipping {f.Name}, already imported on {completedImports[f.Name].Imported.ToString("u")}");
                        continue;
                    }

                    var fileNameSplit = f.Name.Split('.');
                    if (fileNameSplit.Length != 4)
                    {
                        throw new InvalidOperationException($"File {f.Name} do not have 4 components: [Order].[Collection].[Operation].json");
                    }
                    string     collectionName = fileNameSplit[1];
                    ImportMode importMode     = Enum.Parse <ImportMode>(fileNameSplit[2], true);

                    Program.Console($"Importing {f.Name} to collection {collectionName}, mode {importMode}");


                    SyncEntity importResult = new SyncEntity();
                    importResult.FileName = f.Name;

                    try
                    {
                        switch (importMode)
                        {
                        case ImportMode.Drop:
                            dropCollection(collectionName);
                            break;

                        case ImportMode.Delete:
                            deleteFromCollection(collectionName, f);
                            break;

                        case ImportMode.Insert:
                        case ImportMode.Upsert:
                        case ImportMode.Merge:
                            var resultCode = Program.Exec(IMPORT_COMMAND, $"{ConnectionString.ToCommandLine()}{AuthenticationDatabaseToCommandLine()} --collection {collectionName} --type json --mode {importMode.ToString().ToLower()} --stopOnError --file {f.Name}");
                            if (resultCode != 0)
                            {
                                throw new InvalidOperationException($"mongoimport result code {resultCode}, interrupting");
                            }
                            break;

                        case ImportMode.Eval:
                            var evalResultCode = Program.Exec(MONGO_COMMAND, $"{Connection} {f.Name}");
                            if (evalResultCode != 0)
                            {
                                throw new InvalidOperationException($"mongo result code {evalResultCode}, interrupting");
                            }
                            break;

                        case ImportMode.CreateIndex:
                            var text = File.ReadAllText(f.FullName);

                            Program.Console("Index params:");
                            Program.Console(text);

                            var command  = string.Format(CREATE_INDEX, collectionName, text);
                            var fileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".js");
                            File.WriteAllText(fileName, command);

                            try
                            {
                                var createIndexResultCode = Program.Exec(MONGO_COMMAND, $"{Connection} {fileName}");
                                switch (createIndexResultCode)
                                {
                                // no error
                                case 0:
                                    break;

                                case 11000:
                                    throw new InvalidOperationException($"CreateIndex failed with error 'duplicate key error', interrupting");

                                default:
                                    // all error codes with explanation
                                    // https://github.com/mongodb/mongo/blob/master/src/mongo/base/error_codes.err
                                    throw new InvalidOperationException($"CreateIndex result code {createIndexResultCode}, interrupting");
                                }
                            }
                            finally
                            {
                                File.Delete(fileName);
                            }
                            break;

                        default: throw new InvalidOperationException($"Import mode {importMode} not implemented yet");
                        }
                        importResult.Success = true;
                    }
                    finally
                    {
                        SyncCollection.InsertOne(importResult);
                    }
                }
                Program.Console($"Import completed successfully");
            }
            catch (Exception ex)
            {
                Program.Console($"Error during import: {ex.Message}");
                Environment.Exit(1);
            }
        }