async Task <IImmutableList <CommandBase> > IKustoManagementGateway.ReverseEngineerDatabaseAsync(
            CancellationToken ct)
        {
            var tracerTimer = new TracerTimer(_tracer);

            _tracer.WriteLine(true, "Fetch schema commands start");

            var schemaOutputTask   = ExecuteCommandAsync(".show database schema as csl script", ct);
            var mappingsOutputTask = ExecuteCommandAsync(".show database ingestion mappings", ct);
            var schemaOutput       = await schemaOutputTask;
            var mappingsOutput     = await mappingsOutputTask;

            _tracer.WriteLine(true, "Fetch schema commands end");
            tracerTimer.WriteTime(true, "Fetch schema commands time");

            var schemaCommandText = Select(
                schemaOutput,
                r => (string)r["DatabaseSchemaScript"]);
            var schemaCommands  = CommandBase.FromScript(string.Join("\n\n", schemaCommandText), true);
            var mappingCommands = Select(
                mappingsOutput,
                r => new CreateMappingCommand(
                    new EntityName((string)r["Table"]),
                    (string)r["Kind"],
                    new QuotedText((string)r["Name"]),
                    new QuotedText((string)r["Mapping"])))
                                  .Cast <CommandBase>()
                                  .ToImmutableArray();
            var allCommands = schemaCommands
                              .Concat(mappingCommands)
                              .ToImmutableArray();

            return(allCommands);
        }
        async Task IKustoManagementGateway.ExecuteCommandsAsync(
            IEnumerable <CommandBase> commands,
            CancellationToken ct)
        {
            if (commands.Any())
            {
                _tracer.WriteLine(true, ".execute database script commands start");

                var tracerTimer      = new TracerTimer(_tracer);
                var scriptingContext = new ScriptingContext
                {
                    CurrentDatabaseName = new EntityName(_database)
                };
                var commandScripts = commands.Select(c => c.ToScript(scriptingContext));
                var fullScript     = ".execute database script with (ThrowOnErrors=true) <|"
                                     + Environment.NewLine
                                     + string.Join(Environment.NewLine + Environment.NewLine, commandScripts);
                var output = await ExecuteCommandAsync(fullScript, ct);

                _tracer.WriteLine(true, ".execute database script commands end");
                tracerTimer.WriteTime(true, ".execute database script commands time");

                var content = Select(
                    output,
                    r => new
                {
                    Result      = (string)r["Result"],
                    Reason      = (string)r["Reason"],
                    CommandText = (string)r["CommandText"],
                    OperationId = (Guid)r["OperationId"]
                });
                var failedItems = content.Where(t => t.Result != "Completed");

                if (failedItems.Any())
                {
                    var failedItem        = failedItems.First();
                    var failedItemCommand = PackageString(failedItem.CommandText);
                    var allCommands       = string.Join(
                        ", ",
                        content.Select(i => $"({i.Result}:  '{PackageString(i.CommandText)}')"));

                    throw new InvalidOperationException(
                              $"Command failed to execute with reason '{failedItem.Reason}'.  "
                              + $"Operation ID:  {failedItem.OperationId}.  "
                              + $"Cluster URI:  {_clusterUri}.  "
                              + $"Database:  {_database}.  "
                              + $"Command:  '{failedItemCommand}'.  "
                              + $"All commands:  {allCommands}");
                }
            }
        }