예제 #1
0
        public void TestNewDeploymentNoErrors()
        {
            var newDbName = "AdventureWorks_UT_New1";
            var server    = new TOM.Server();

            server.Connect("localhost");
            if (server.Databases.ContainsName(newDbName))
            {
                server.Databases[newDbName].Drop();
            }

            var handler = new TabularModelHandler("AdventureWorks.bim");

            var results = TabularDeployer.Deploy(handler, "localhost", newDbName);

            Assert.AreEqual(0, results.Issues.Count);
            Assert.AreNotEqual(0, results.Unprocessed.Count);
            Assert.AreEqual(0, results.Warnings.Count);

            server.Refresh();
            if (server.Databases.ContainsName(newDbName))
            {
                server.Databases[newDbName].Drop();
            }
        }
예제 #2
0
        public void Database_Deploy()
        {
            ExpressionEditor_AcceptEdit();

            var f = new DeployForm();

            f.PreselectDb = LastDeploymentDb;
            var res = f.ShowDialog();

            if (res == DialogResult.Cancel)
            {
                return;
            }

            LastDeploymentDb = f.PreselectDb;

            // Backup database metadata
            if (Preferences.Current.BackupOnSave)
            {
                var backupFilename = string.Format("{0}\\Backup_{1}_{2}.zip", Preferences.Current.BackupLocation, Handler.Database.Name, DateTime.Now.ToString("yyyyMMddhhmmssfff"));
                TabularDeployer.SaveModelMetadataBackup(f.DeployTargetServer.ConnectionString, f.DeployTargetDatabaseID, backupFilename);
            }


            UI.StatusLabel.Text = "Deploying...";
            Application.DoEvents();
            using (new Hourglass())
            {
                bool   cancelled = false;
                bool   error     = false;
                string message   = "";

                using (var df = new DeployingForm())
                {
                    df.DeployAction = () =>
                    {
                        try
                        {
                            Program.UpdateDeploymentMetadata(Handler.Model, DeploymentModeMetadata.WizardUI);
                            TabularDeployer.Deploy(Handler, f.DeployTargetServer.ConnectionString, f.DeployTargetDatabaseID, f.DeployOptions, df.CancelToken);
                        }
                        catch (Exception ex)
                        {
                            cancelled = df.CancelToken.IsCancellationRequested;
                            error     = !cancelled;
                            message   = ex.Message;
                            df.ThreadClose();
                        }
                    };
                    df.ShowDialog();
                }

                if (error || cancelled)
                {
                    MessageBox.Show(message, error ? "Error occured during deployment" : "Deploy cancelled", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                UI.StatusLabel.Text = error ? "Deploy failed!" : cancelled ? "Deploy cancelled!" : "Deploy succeeded!";
            }
        }
예제 #3
0
        public void TestNewDeploymentCalcColumnError()
        {
            var newDbName = "AdventureWorks_UT_New3";
            var server    = new TOM.Server();

            server.Connect("localhost");
            if (server.Databases.ContainsName(newDbName))
            {
                server.Databases[newDbName].Drop();
            }

            var handler = new TabularModelHandler("AdventureWorks.bim");

            handler.Model.Tables["Employee"].AddCalculatedColumn("ErrorTest", "xxx");

            var results = TabularDeployer.Deploy(handler, "localhost", newDbName);

            Assert.AreNotEqual(0, results.Issues.Count);
            Assert.AreNotEqual(0, results.Unprocessed.Count);
            Assert.AreNotEqual(0, results.Warnings.Count);

            server.Refresh();
            if (server.Databases.ContainsName(newDbName))
            {
                server.Databases[newDbName].Drop();
            }
        }
예제 #4
0
        public void TestExistingDeployment()
        {
            var s = new Server();

            s.Connect("localhost");
            if (s.Databases.ContainsName("AdventureWorks_X"))
            {
                s.Databases["AdventureWorks_X"].Drop();
            }
            s.Disconnect();

            var orgModel = new TabularModelHandler("AdventureWorks2.bim");

            TabularDeployer.Deploy(orgModel, "localhost", "AdventureWorks_X");


            var modifiedModel = new TabularModelHandler("AdventureWorks.bim");

            foreach (var p in modifiedModel.Model.Perspectives.ToList())
            {
                p.Delete();
            }
            modifiedModel.Model.Tables["Product"].Delete();

            TabularDeployer.Deploy(modifiedModel, "localhost", "AdventureWorks_X");

            TabularDeployer.Deploy(orgModel, "localhost", "AdventureWorks_X");
        }
예제 #5
0
        public void TestNewDeploymentMeasureError()
        {
            var newDbName = "AdventureWorks_UT_New2";
            var server    = new TOM.Server();

            server.Connect(Constants.ServerName);
            if (server.Databases.ContainsName(newDbName))
            {
                server.Databases[newDbName].Drop();
            }

            var handler = new TabularModelHandler("TestData\\AdventureWorks.bim");

            handler.Model.Tables["Employee"].AddMeasure("ErrorTest", "xxx");

            var results = TabularDeployer.Deploy(handler, Constants.ServerName, newDbName);

            Assert.AreNotEqual(0, results.Issues.Count);
            Assert.AreNotEqual(0, results.Unprocessed.Count);
            Assert.AreEqual(0, results.Warnings.Count);

            server.Refresh();
            if (server.Databases.ContainsName(newDbName))
            {
                server.Databases[newDbName].Drop();
            }
        }
예제 #6
0
        private void Ensure1500ModelExists()
        {
            var testModel = ObjectHandlingTests.CreateTestModel(compatibilityLevel: 1500);

            TabularDeployer.Deploy(testModel, Constants.AasServerName, "TomWrapperTest1500", new DeploymentOptions {
                DeployMode = DeploymentMode.CreateOrAlter
            });
        }
        public TabularModelHandler ResetAndConnect()
        {
            CreateTestModel(TestFileName);
            var tm = new TabularModelHandler(TestFileName);

            TabularDeployer.Deploy(tm, Constants.ServerName, TestDBName, DeploymentOptions.Full);

            return(new TabularModelHandler(Constants.ServerName, TestDBName));
        }
예제 #8
0
        private void Database_Save()
        {
            UI.ErrorLabel.Text = "";

            try
            {
                var conflictInfo = Handler.CheckConflicts();
                if (conflictInfo.Conflict)
                {
                    var res = MessageBox.Show(string.Format("Changes have been made to the deployed version of the model, since it was loaded into Tabular Editor.\n\nDeployed model version: {0} (changed {1})\nCurrent model version: {2}\n\nDo you want to overwrite the deployed model?",
                                                            conflictInfo.DatabaseVersion, conflictInfo.DatabaseLastUpdate, conflictInfo.LoadedVersion),
                                              "Change conflict", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                    if (res == DialogResult.No)
                    {
                        return;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\n\nSave the model as a file to make sure you do not lose any work. In case the database connection was lost, you can still apply your changes to the database by using the \"Model > Deploy\" option.", "Could not save metadata changes to database", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            using (new Hourglass())
            {
                UI.StatusLabel.Text = "Saving changes to DB...";
                Application.DoEvents();

                if (Preferences.Current.BackupOnSave)
                {
                    var backupFilename = string.Format("{0}\\Backup_{1}_{2}.zip", Preferences.Current.BackupLocation, Handler.Database.Name, DateTime.Now.ToString("yyyyMMddhhmmssfff"));
                    try
                    {
                        TabularDeployer.SaveModelMetadataBackup(Handler.Database.Server.ConnectionString, Handler.Database.ID, backupFilename);
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(e.Message, "Unable to save metadata backup", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                }

                try
                {
                    Program.UpdateDeploymentMetadata(Handler.Model, DeploymentModeMetadata.SaveUI);
                    Handler.SaveDB();
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message + "\n\nSave the model as a file to make sure you do not lose any work. In case the database connection was lost, you can still apply your changes to the database by using the \"Model > Deploy\" option.", "Could not save metadata changes to database", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                UI.TreeView.Refresh();
            }
        }
예제 #9
0
        private void btnTMSL_Click(object sender, EventArgs e)
        {
            var tmslForm = new ClipForm();

            tmslForm.Text = "TMSL Script";
            using (new Hourglass())
            {
                tmslForm.txtCode.Text = TabularDeployer.GetTMSL(Handler.Database,
                                                                DeployTargetServer, DeployTargetDatabaseName, DeployOptions);
            }
            tmslForm.ShowDialog();
        }
예제 #10
0
        public void TestMethod1()
        {
            if (Directory.Exists("TestData\\CalcGroupOrderTest"))
            {
                Directory.Delete("TestData\\CalcGroupOrderTest", true);
            }
            ZipFile.ExtractToDirectory("TestData\\CalcGroupOrderTest.zip", "TestData\\CalcGroupOrderTest");
            var handler = new TabularModelHandler("TestData\\CalcGroupOrderTest");
            var model   = handler.Model;

            var tmsl = TabularDeployer.DeployNewTMSL(handler.Database, "db", DeploymentOptions.Full, false);

            Assert.AreEqual(expectedTmsl, tmsl);
        }
        public void Database_Deploy()
        {
            ExpressionEditor_AcceptEdit();

            var f   = new DeployForm();
            var res = f.ShowDialog();

            if (res == DialogResult.Cancel)
            {
                return;
            }

            // Backup database metadata
            if (Preferences.Current.BackupOnSave)
            {
                var backupFilename = string.Format("{0}\\Backup_{1}_{2}.zip", Preferences.Current.BackupLocation, Handler.Database.Name, DateTime.Now.ToString("yyyyMMddhhmmssfff"));
                TabularDeployer.SaveModelMetadataBackup(f.DeployTargetServer.ConnectionString, f.DeployTargetDatabaseID, backupFilename);
            }


            UI.StatusLabel.Text = "Deploying...";
            Application.DoEvents();
            using (new Hourglass())
            {
                var df    = new DeployingForm();
                var error = false;
                df.DeployAction = () =>
                {
                    try
                    {
                        TabularDeployer.Deploy(Handler, f.DeployTargetServer.ConnectionString, f.DeployTargetDatabaseID, f.DeployOptions);
                    }
                    catch (Exception ex)
                    {
                        error = true;
                        df.ThreadClose();
                        MessageBox.Show(ex.Message, "Error occured during deployment", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                };
                df.ShowDialog();
                UI.StatusLabel.Text = error ? "Deploy failed!" : "Deploy succeeded!";
            }
        }
예제 #12
0
        public void DeploymentErrorMessages()
        {
            var handler = new TabularModelHandler("AdventureWorks.bim");
            var options = new DeploymentOptions {
                DeployMode = DeploymentMode.CreateOrAlter
            };
            var result = TabularDeployer.Deploy(handler, "localhost", "AdventureWorks_RegTest_2_8_5", options);

            Assert.AreEqual(0, result.Issues.Count);

            var errorMeasure = handler.Model.Tables[0].AddMeasure("ErrorMeasure", "SYNTAX ERROR");

            result = TabularDeployer.Deploy(handler, "localhost", "AdventureWorks_RegTest_2_8_5", options);

            Assert.AreEqual(1, result.Issues.Count);

            errorMeasure.Delete();
            result = TabularDeployer.Deploy(handler, "localhost", "AdventureWorks_RegTest_2_8_5", options);
            Assert.AreEqual(0, result.Issues.Count);
        }
예제 #13
0
        internal bool HandleCommandLine(string[] args)
        {
            var upperArgList = args.Select(arg => arg.ToUpper()).ToList();
            var argList      = args.Select(arg => arg).ToList();

            if (upperArgList.Contains("-?") || upperArgList.Contains("/?") || upperArgList.Contains("-H") || upperArgList.Contains("/H") || upperArgList.Contains("HELP"))
            {
                OutputUsage();
                return(true);
            }

            EnableVSTS = upperArgList.IndexOf("-VSTS") > -1 || upperArgList.IndexOf("-V") > -1;
            var warnOnUnprocessed = upperArgList.IndexOf("-WARN") > -1 || upperArgList.IndexOf("-W") > -1;
            var errorOnDaxErr     = upperArgList.IndexOf("-ERR") > -1 || upperArgList.IndexOf("-E") > -1;

            TabularModelHandler h;

            if (args.Length == 2 || args[2].StartsWith("-"))
            {
                // File argument provided (either alone or with switches), i.e.:
                //      TabularEditor.exe myfile.bim
                //      TabularEditor.exe myfile.bim -...

                if (!File.Exists(args[1]) && !File.Exists(args[1] + "\\database.json"))
                {
                    Error("File not found: {0}", args[1]);
                    return(true);
                }
                else
                {
                    // If nothing else was specified on the command-line, open the UI:
                    if (args.Length == 2)
                    {
                        return(false);
                    }
                }

                try
                {
                    h = new TOMWrapper.TabularModelHandler(args[1]);
                }
                catch (Exception e)
                {
                    Error("Error loading file: " + e.Message);
                    return(true);
                }
            }
            else if (args.Length == 3 || args[3].StartsWith("-"))
            {
                // Server + Database argument provided (either alone or with switches), i.e.:
                //      TabularEditor.exe localhost AdventureWorks
                //      TabularEditor.exe localhost AdventureWorks -...
                // If nothing else was specified on the command-line, open the UI:
                if (args.Length == 3)
                {
                    return(false);
                }

                try
                {
                    h = new TOMWrapper.TabularModelHandler(args[1], args[2]);
                }
                catch (Exception e)
                {
                    Error("Error loading model: " + e.Message);
                    return(true);
                }
            }
            else
            {
                // Otherwise, it's nonsensical
                return(false);
            }

            string script     = null;
            string scriptFile = null;

            var    doTestRun   = upperArgList.IndexOf("-T");
            string testRunFile = null;

            if (doTestRun == -1)
            {
                doTestRun = upperArgList.IndexOf("-TRX");
            }
            if (doTestRun > -1)
            {
                if (upperArgList.Count <= doTestRun || upperArgList[doTestRun + 1].StartsWith("-"))
                {
                    Error("Invalid argument syntax.\n");
                    OutputUsage();
                    return(true);
                }
                Program.testRun = new TestRun(h.Database?.Name ?? h.Source);
                testRunFile     = argList[doTestRun + 1];
            }

            var doScript = upperArgList.IndexOf("-SCRIPT");

            if (doScript == -1)
            {
                doScript = upperArgList.IndexOf("-S");
            }
            if (doScript > -1)
            {
                if (upperArgList.Count <= doScript)
                {
                    Error("Invalid argument syntax.\n");
                    OutputUsage();
                    return(true);
                }
                scriptFile = argList[doScript + 1];
                script     = File.Exists(scriptFile) ? File.ReadAllText(scriptFile) : scriptFile;
            }

            var doCheckDs = upperArgList.IndexOf("-SCHEMACHECK");

            if (doCheckDs == -1)
            {
                doCheckDs = upperArgList.IndexOf("-SC");
            }

            string saveToFolderOutputPath = null;
            string saveToFolderReplaceId  = null;

            var doSaveToFolder = upperArgList.IndexOf("-FOLDER");

            if (doSaveToFolder == -1)
            {
                doSaveToFolder = upperArgList.IndexOf("-F");
            }
            if (doSaveToFolder > -1)
            {
                if (upperArgList.Count <= doSaveToFolder)
                {
                    Error("Invalid argument syntax.\n");
                    OutputUsage();
                    return(true);
                }
                saveToFolderOutputPath = argList[doSaveToFolder + 1];
                if (doSaveToFolder + 2 < argList.Count && !argList[doSaveToFolder + 2].StartsWith("-"))
                {
                    saveToFolderReplaceId = argList[doSaveToFolder + 2];
                }
                var directoryName = new FileInfo(saveToFolderOutputPath).Directory.FullName;
                Directory.CreateDirectory(saveToFolderOutputPath);
            }

            string buildOutputPath = null;
            string buildReplaceId  = null;

            var doSave = upperArgList.IndexOf("-BUILD");

            if (doSave == -1)
            {
                doSave = upperArgList.IndexOf("-B");
            }
            if (doSave == -1)
            {
                doSave = upperArgList.IndexOf("-BIM");
            }
            if (doSave > -1)
            {
                if (upperArgList.Count <= doSave)
                {
                    Error("Invalid argument syntax.\n");
                    OutputUsage();
                    return(true);
                }
                buildOutputPath = argList[doSave + 1];
                if (doSave + 2 < argList.Count && !argList[doSave + 2].StartsWith("-"))
                {
                    buildReplaceId = argList[doSave + 2];
                }
                var directoryName = new FileInfo(buildOutputPath).Directory.FullName;
                Directory.CreateDirectory(directoryName);
            }

            if (doSaveToFolder > -1 && doSave > -1)
            {
                Error("-FOLDER and -BUILD arguments are mutually exclusive.\n");
                OutputUsage();
                return(true);
            }

            // Load model:
            Console.WriteLine("Loading model...");

            if (!string.IsNullOrEmpty(script))
            {
                Console.WriteLine("Executing script...");

                System.CodeDom.Compiler.CompilerResults result;
                Scripting.ScriptOutputForm.Reset(false);
                var dyn = ScriptEngine.CompileScript(script, out result);
                //nUnit.StartSuite("Script Compilation");
                if (result.Errors.Count > 0)
                {
                    Error("Script compilation errors:");
                    var errIndex = 0;
                    foreach (System.CodeDom.Compiler.CompilerError err in result.Errors)
                    {
                        errIndex++;
                        ErrorX(err.ErrorText, scriptFile, err.Line, err.Column, err.ErrorNumber);
                        //nUnit.Failure("Script Compilation", $"Compilation Error #{errIndex}", err.ErrorText, $"{scriptFile} line {err.Line}, column {err.Column}");
                    }
                    return(true);
                }
                try
                {
                    h.BeginUpdate("script");
                    dyn.Invoke(h.Model, null);
                    h.EndUpdateAll();
                }
                catch (Exception ex)
                {
                    Error("Script execution error: " + ex.Message);
                    return(true);
                }
                finally
                {
                    h.Model.Database.CloseReader();
                }
            }

            if (doCheckDs > -1)
            {
                Console.WriteLine("Checking source schema...");
                ScriptHelper.SchemaCheck(h.Model);
            }

            if (!string.IsNullOrEmpty(buildOutputPath))
            {
                Console.WriteLine("Building Model.bim file...");
                if (buildReplaceId != null)
                {
                    h.Database.Name = buildReplaceId; h.Database.ID = buildReplaceId;
                }
                h.Save(buildOutputPath, SaveFormat.ModelSchemaOnly, SerializeOptions.Default);
            }
            else if (!string.IsNullOrEmpty(saveToFolderOutputPath))
            {
                Console.WriteLine("Saving Model.bim file to Folder Output Path ...");
                if (buildReplaceId != null)
                {
                    h.Database.Name = buildReplaceId; h.Database.ID = buildReplaceId;
                }

                //Note the last parameter, we use whatever SerializeOptions are already in the file
                h.Save(saveToFolderOutputPath, SaveFormat.TabularEditorFolder, null, true);
            }

            var replaceMap = new Dictionary <string, string>();

            var analyze = upperArgList.IndexOf("-ANALYZE");

            if (analyze == -1)
            {
                analyze = upperArgList.IndexOf("-A");
            }
            if (analyze > -1)
            {
                var rulefile = analyze + 1 < argList.Count ? argList[analyze + 1] : "";
                if (rulefile.StartsWith("-") || string.IsNullOrEmpty(rulefile))
                {
                    rulefile = null;
                }

                Console.WriteLine("Running Best Practice Analyzer...");
                Console.WriteLine("=================================");

                var analyzer = new BPA.Analyzer();
                analyzer.SetModel(h.Model, h.SourceType == ModelSourceType.Database ? null : FileSystemHelper.DirectoryFromPath(h.Source));

                BPA.BestPracticeCollection suppliedRules = null;
                if (!string.IsNullOrEmpty(rulefile))
                {
                    if (File.Exists(rulefile))
                    {
                        try
                        {
                            suppliedRules = BPA.BestPracticeCollection.GetCollectionFromFile(Environment.CurrentDirectory, rulefile);
                        }
                        catch
                        {
                            Error("Invalid rulefile: {0}", rulefile);
                            return(true);
                        }
                    }
                    else
                    {
                        suppliedRules = BPA.BestPracticeCollection.GetCollectionFromUrl(rulefile);
                        if (suppliedRules.Count == 0)
                        {
                            Error("No rules defined in specified URL: {0}", rulefile);
                            return(true);
                        }
                    }
                }

                IEnumerable <BPA.AnalyzerResult> bpaResults;
                if (suppliedRules == null)
                {
                    bpaResults = analyzer.AnalyzeAll();
                }
                else
                {
                    var effectiveRules = analyzer.GetEffectiveRules(false, false, true, true, suppliedRules);
                    bpaResults = analyzer.Analyze(effectiveRules);
                }

                bool none = true;
                foreach (var res in bpaResults.Where(r => !r.Ignored))
                {
                    if (res.InvalidCompatibilityLevel)
                    {
                        Console.WriteLine("Skipping rule '{0}' as it does not apply to Compatibility Level {1}.", res.RuleName, h.CompatibilityLevel);
                    }
                    else
                    if (res.RuleHasError)
                    {
                        none = false;
                        Error("Error on rule '{0}': {1}", res.RuleName, res.RuleError);
                    }
                    else
                    {
                        none = false;
                        if (res.Object != null)
                        {
                            var text = string.Format("{0} {1} violates rule \"{2}\"",
                                                     res.Object.GetTypeName(),
                                                     (res.Object as IDaxObject)?.DaxObjectFullName ?? res.ObjectName,
                                                     res.RuleName
                                                     );
                            if (res.Rule.Severity <= 1)
                            {
                                Console.WriteLine(text);
                            }
                            else if (res.Rule.Severity == 2)
                            {
                                Warning(text);
                            }
                            else if (res.Rule.Severity >= 3)
                            {
                                Error(text);
                            }
                        }
                    }
                }
                if (none)
                {
                    Console.WriteLine("No objects in violation of Best Practices.");
                }
                Console.WriteLine("=================================");
            }

            var deploy = upperArgList.IndexOf("-DEPLOY");

            if (deploy == -1)
            {
                deploy = upperArgList.IndexOf("-D");
            }
            if (deploy > -1)
            {
                var serverName = argList.Skip(deploy + 1).FirstOrDefault(); if (serverName == null || serverName.StartsWith("-"))
                {
                    serverName = null;
                }
                var databaseID = argList.Skip(deploy + 2).FirstOrDefault(); if (databaseID != null && databaseID.StartsWith("-"))
                {
                    databaseID = null;
                }

                // Perform direct save:
                if (serverName == null)
                {
                    var nextSwitch     = upperArgList.Skip(deploy + 1).FirstOrDefault();
                    var deploySwitches = new[] { "-L", "-LOGIN", "-O", "-OVERWRITE", "-C", "-CONNECTIONS", "-P", "-PARTITIONS", "-R", "-ROLES", "-M", "-MEMBERS", "-X", "-XMLA" };
                    if (deploySwitches.Contains(nextSwitch))
                    {
                        Error("Invalid argument syntax.\n");
                        OutputUsage();
                        return(true);
                    }

                    Console.WriteLine("Saving model metadata back to source...");
                    if (h.SourceType == ModelSourceType.Database)
                    {
                        try
                        {
                            h.SaveDB();
                            Console.WriteLine("Model metadata saved.");

                            var deploymentResult = h.GetLastDeploymentResults();
                            foreach (var err in deploymentResult.Issues)
                            {
                                if (errorOnDaxErr)
                                {
                                    Error(err);
                                }
                                else
                                {
                                    Warning(err);
                                }
                            }
                            foreach (var err in deploymentResult.Warnings)
                            {
                                Warning(err);
                            }
                            foreach (var err in deploymentResult.Unprocessed)
                            {
                                if (warnOnUnprocessed)
                                {
                                    Warning(err);
                                }
                                else
                                {
                                    Console.WriteLine(err);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Error("Save failed: " + ex.Message);
                        }
                    }
                    else
                    {
                        try
                        {
                            h.Save(h.Source, h.SourceType == ModelSourceType.Folder ? SaveFormat.TabularEditorFolder : h.SourceType == ModelSourceType.Pbit ? SaveFormat.PowerBiTemplate : SaveFormat.ModelSchemaOnly, h.SerializeOptions, true);
                            Console.WriteLine("Model metadata saved.");
                        }
                        catch (Exception ex)
                        {
                            Error("Save failed: " + ex.Message);
                        }
                    }
                    return(true);
                }

                var conn = upperArgList.IndexOf("-CONNECTIONS");
                if (conn == -1)
                {
                    conn = upperArgList.IndexOf("-C");
                }
                if (conn > -1)
                {
                    var replaces = argList.Skip(conn + 1).TakeWhile(s => s[0] != '-').ToList();

                    if (replaces.Count > 0 && replaces.Count % 2 == 0)
                    {
                        // Placeholder replacing:
                        for (var index = 0; index < replaces.Count; index = index + 2)
                        {
                            replaceMap.Add(replaces[index], replaces[index + 1]);
                        }
                    }
                }

                string userName = null;
                string password = null;
                var    options  = DeploymentOptions.StructureOnly;

                var switches = args.Skip(deploy + 1).Where(arg => arg.StartsWith("-")).Select(arg => arg.ToUpper()).ToList();

                if (string.IsNullOrEmpty(serverName) || string.IsNullOrEmpty(databaseID))
                {
                    Error("Invalid argument syntax.\n");
                    OutputUsage();
                    return(true);
                }
                if (switches.Contains("-L") || switches.Contains("-LOGIN"))
                {
                    var switchPos = upperArgList.IndexOf("-LOGIN"); if (switchPos == -1)
                    {
                        switchPos = upperArgList.IndexOf("-L");
                    }
                    userName = argList.Skip(switchPos + 1).FirstOrDefault(); if (userName != null && userName.StartsWith("-"))
                    {
                        userName = null;
                    }
                    password = argList.Skip(switchPos + 2).FirstOrDefault(); if (password != null && password.StartsWith("-"))
                    {
                        password = null;
                    }
                    if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
                    {
                        Error("Missing username or password.\n");
                        OutputUsage();
                        return(true);
                    }
                    switches.Remove("-L"); switches.Remove("-LOGIN");
                }
                if (switches.Contains("-O") || switches.Contains("-OVERWRITE"))
                {
                    options.DeployMode = DeploymentMode.CreateOrAlter;
                    switches.Remove("-O"); switches.Remove("-OVERWRITE");
                }
                else
                {
                    options.DeployMode = DeploymentMode.CreateDatabase;
                }
                if (switches.Contains("-P") || switches.Contains("-PARTITIONS"))
                {
                    options.DeployPartitions = true;
                    switches.Remove("-P"); switches.Remove("-PARTITIONS");
                }
                if (switches.Contains("-C") || switches.Contains("-CONNECTIONS"))
                {
                    options.DeployConnections = true;
                    switches.Remove("-C"); switches.Remove("-CONNECTIONS");
                }
                if (switches.Contains("-R") || switches.Contains("-ROLES"))
                {
                    options.DeployRoles = true;
                    switches.Remove("-R"); switches.Remove("-ROLES");

                    if (switches.Contains("-M") || switches.Contains("-MEMBERS"))
                    {
                        options.DeployRoleMembers = true;
                        switches.Remove("-M"); switches.Remove("-MEMBERS");
                    }
                }
                var    xmla_scripting_only = switches.Contains("-X") || switches.Contains("-XMLA");
                string xmla_script_file    = null;
                if (xmla_scripting_only)
                {
                    var switchPos = upperArgList.IndexOf("-XMLA"); if (switchPos == -1)
                    {
                        switchPos = upperArgList.IndexOf("-X");
                    }
                    xmla_script_file = argList.Skip(switchPos + 1).FirstOrDefault(); if (String.IsNullOrWhiteSpace(xmla_script_file) || xmla_script_file.StartsWith("-"))
                    {
                        xmla_script_file = null;
                    }
                    if (string.IsNullOrEmpty(xmla_script_file))
                    {
                        Error("Missing xmla_script_file.\n");
                        OutputUsage();
                        return(true);
                    }
                    switches.Remove("-X");
                    switches.Remove("-XMLA");
                }

                /*if(switches.Count > 0)
                 * {
                 *  Error("Unknown switch {0}\n", switches[0]);
                 *  OutputUsage();
                 *  return true;
                 * }*/

                try
                {
                    if (replaceMap.Count > 0)
                    {
                        Console.WriteLine("Switching connection string placeholders...");
                        foreach (var map in replaceMap)
                        {
                            h.Model.DataSources.SetPlaceholder(map.Key, map.Value);
                        }
                    }

                    var cs = string.IsNullOrEmpty(userName) ? TabularConnection.GetConnectionString(serverName) :
                             TabularConnection.GetConnectionString(serverName, userName, password);
                    if (xmla_scripting_only)
                    {
                        Console.WriteLine("Generating XMLA/TMSL script...");
                        var s = new TOM.Server();
                        s.Connect(cs);
                        var xmla = TabularDeployer.GetTMSL(h.Database, s, databaseID, options);
                        using (var sw = new StreamWriter(xmla_script_file))
                        {
                            sw.Write(xmla);
                        }
                        Console.WriteLine("XMLA/TMSL script generated.");
                    }
                    else
                    {
                        Console.WriteLine("Deploying...");
                        h.Model.UpdateDeploymentMetadata(DeploymentModeMetadata.CLI);
                        var deploymentResult = TabularDeployer.Deploy(h, cs, databaseID, options);
                        Console.WriteLine("Deployment succeeded.");
                        foreach (var err in deploymentResult.Issues)
                        {
                            if (errorOnDaxErr)
                            {
                                Error(err);
                            }
                            else
                            {
                                Warning(err);
                            }
                        }
                        foreach (var err in deploymentResult.Warnings)
                        {
                            Warning(err);
                        }
                        foreach (var err in deploymentResult.Unprocessed)
                        {
                            if (warnOnUnprocessed)
                            {
                                Warning(err);
                            }
                            else
                            {
                                Console.WriteLine(err);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Error($"{(xmla_scripting_only ? "Script generation" : "Deployment")} failed! {ex.Message}");
                }
            }
            if (Program.testRun != null)
            {
                Program.testRun.SerializeAsVSTest(testRunFile);
                Console.WriteLine("VSTest XML file saved: " + testRunFile);
            }

            return(true);
        }
예제 #14
0
        public void SetupTomwrapperTest()
        {
            var handler = new TabularModelHandler(@"TestData\AdventureWorks.bim");

            TabularDeployer.Deploy(handler, Constants.ServerName, "TomWrapperTest");
        }
예제 #15
0
        void Deploy(string serverName, string databaseID, int doDeploy)
        {
            // Perform direct save:
            if (serverName == null)
            {
                var nextSwitch     = upperArgList.Skip(doDeploy + 1).FirstOrDefault();
                var deploySwitches = new[] { "-L", "-LOGIN", "-O", "-OVERWRITE", "-C", "-CONNECTIONS", "-P", "-PARTITIONS", "-Y", "-SKIPPOLICY", "-R", "-ROLES", "-M", "-MEMBERS", "-X", "-XMLA" };
                if (deploySwitches.Contains(nextSwitch))
                {
                    Error("Invalid argument syntax.");
                    OutputUsage();
                    throw new CommandLineException();
                }

                Console.WriteLine("Saving model metadata back to source...");
                if (Handler.SourceType == ModelSourceType.Database)
                {
                    try
                    {
                        Handler.SaveDB();
                        Console.WriteLine("Model metadata saved.");

                        var deploymentResult = Handler.GetLastDeploymentResults();
                        foreach (var err in deploymentResult.Issues)
                        {
                            if (errorOnDaxErr)
                            {
                                Error(err);
                            }
                            else
                            {
                                Warning(err);
                            }
                        }
                        foreach (var err in deploymentResult.Warnings)
                        {
                            Warning(err);
                        }
                        foreach (var err in deploymentResult.Unprocessed)
                        {
                            if (warnOnUnprocessed)
                            {
                                Warning(err);
                            }
                            else
                            {
                                Console.WriteLine(err);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Error("Save failed: " + ex.Message);
                    }
                }
                else
                {
                    try
                    {
                        Handler.Save(Handler.Source, Handler.SourceType == ModelSourceType.Folder ? SaveFormat.TabularEditorFolder : Handler.SourceType == ModelSourceType.Pbit ? SaveFormat.PowerBiTemplate : SaveFormat.ModelSchemaOnly, Handler.SerializeOptions, true);
                        Console.WriteLine("Model metadata saved.");
                    }
                    catch (Exception ex)
                    {
                        Error("Save failed: " + ex.Message);
                    }
                }
                throw new CommandLineException();
            }

            var conn = upperArgList.IndexOf("-CONNECTIONS");

            if (conn == -1)
            {
                conn = upperArgList.IndexOf("-C");
            }
            if (conn > -1)
            {
                var replaces = argList.Skip(conn + 1).TakeWhile(s => s[0] != '-').ToList();

                if (replaces.Count > 0 && replaces.Count % 2 == 0)
                {
                    // Placeholder replacing:
                    for (var index = 0; index < replaces.Count; index = index + 2)
                    {
                        replaceMap.Add(replaces[index], replaces[index + 1]);
                    }
                }
            }

            string userName = null;
            string password = null;
            var    options  = DeploymentOptions.StructureOnly;

            var switches = argList.Skip(doDeploy + 1).Where(arg => arg.StartsWith("-")).Select(arg => arg.ToUpper()).ToList();

            if (string.IsNullOrEmpty(serverName) || string.IsNullOrEmpty(databaseID))
            {
                Error("Invalid argument syntax.\n");
                OutputUsage();
                throw new CommandLineException();
            }
            if (switches.Contains("-L") || switches.Contains("-LOGIN"))
            {
                var switchPos = upperArgList.IndexOf("-LOGIN"); if (switchPos == -1)
                {
                    switchPos = upperArgList.IndexOf("-L");
                }
                userName = argList.Skip(switchPos + 1).FirstOrDefault(); if (userName != null && userName.StartsWith("-"))
                {
                    userName = null;
                }
                password = argList.Skip(switchPos + 2).FirstOrDefault(); if (password != null && password.StartsWith("-"))
                {
                    password = null;
                }
                if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
                {
                    Error("Missing username or password.\n");
                    OutputUsage();
                    throw new CommandLineException();
                }
                switches.Remove("-L"); switches.Remove("-LOGIN");
            }
            if (switches.Contains("-O") || switches.Contains("-OVERWRITE"))
            {
                options.DeployMode = DeploymentMode.CreateOrAlter;
                switches.Remove("-O"); switches.Remove("-OVERWRITE");
            }
            else
            {
                options.DeployMode = DeploymentMode.CreateDatabase;
            }
            if (switches.Contains("-P") || switches.Contains("-PARTITIONS"))
            {
                options.DeployPartitions = true;
                switches.Remove("-P"); switches.Remove("-PARTITIONS");

                if (switches.Contains("-Y") || switches.Contains("-SKIPPOLICY"))
                {
                    options.SkipRefreshPolicyPartitions = true;
                    switches.Remove("-Y"); switches.Remove("-SKIPPOLICY");
                }
            }
            if (switches.Contains("-C") || switches.Contains("-CONNECTIONS"))
            {
                options.DeployConnections = true;
                switches.Remove("-C"); switches.Remove("-CONNECTIONS");
            }
            if (switches.Contains("-R") || switches.Contains("-ROLES"))
            {
                options.DeployRoles = true;
                switches.Remove("-R"); switches.Remove("-ROLES");

                if (switches.Contains("-M") || switches.Contains("-MEMBERS"))
                {
                    options.DeployRoleMembers = true;
                    switches.Remove("-M"); switches.Remove("-MEMBERS");
                }
            }
            var    xmla_scripting_only = switches.Contains("-X") || switches.Contains("-XMLA");
            string xmla_script_file    = null;

            if (xmla_scripting_only)
            {
                var switchPos = upperArgList.IndexOf("-XMLA"); if (switchPos == -1)
                {
                    switchPos = upperArgList.IndexOf("-X");
                }
                xmla_script_file = argList.Skip(switchPos + 1).FirstOrDefault(); if (String.IsNullOrWhiteSpace(xmla_script_file) || xmla_script_file.StartsWith("-"))
                {
                    xmla_script_file = null;
                }
                if (string.IsNullOrEmpty(xmla_script_file))
                {
                    Error("Missing xmla_script_file.\n");
                    OutputUsage();
                    throw new CommandLineException();
                }
                switches.Remove("-X");
                switches.Remove("-XMLA");
            }

            try
            {
                if (replaceMap.Count > 0)
                {
                    Console.WriteLine("Switching connection string placeholders...");
                    foreach (var map in replaceMap)
                    {
                        Handler.Model.DataSources.SetPlaceholder(map.Key, map.Value);
                    }
                }

                var cs = string.IsNullOrEmpty(userName) ? TabularConnection.GetConnectionString(serverName, Program.ApplicationName) :
                         TabularConnection.GetConnectionString(serverName, userName, password, Program.ApplicationName);
                if (xmla_scripting_only)
                {
                    Console.WriteLine("Generating XMLA/TMSL script...");
                    var s = new TOM.Server();
                    s.Connect(cs);
                    var xmla = TabularDeployer.GetTMSL(Handler.Database, s, databaseID, options);
                    using (var sw = new StreamWriter(xmla_script_file))
                    {
                        sw.Write(xmla);
                    }
                    Console.WriteLine("XMLA/TMSL script generated.");
                }
                else
                {
                    Console.WriteLine("Deploying...");
                    Handler.Model.UpdateDeploymentMetadata(DeploymentModeMetadata.CLI);
                    var deploymentResult = TabularDeployer.Deploy(Handler, cs, databaseID, options);
                    Console.WriteLine("Deployment succeeded.");
                    foreach (var err in deploymentResult.Issues)
                    {
                        if (errorOnDaxErr)
                        {
                            Error(err);
                        }
                        else
                        {
                            Warning(err);
                        }
                    }
                    foreach (var err in deploymentResult.Warnings)
                    {
                        Warning(err);
                    }
                    foreach (var err in deploymentResult.Unprocessed)
                    {
                        if (warnOnUnprocessed)
                        {
                            Warning(err);
                        }
                        else
                        {
                            Console.WriteLine(err);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Error($"{(xmla_scripting_only ? "Script generation" : "Deployment")} failed! {ex.Message}");
            }
        }
 public DeploymentResult GetLastDeploymentResults()
 {
     return(TabularDeployer.GetLastDeploymentResults(database));
 }
예제 #17
0
        static bool HandleCommandLine(string[] args)
        {
            var upperArgList = args.Select(arg => arg.ToUpper()).ToList();
            var argList      = args.Select(arg => arg).ToList();

            if (upperArgList.Contains("-?") || upperArgList.Contains("/?") || upperArgList.Contains("-H") || upperArgList.Contains("/H") || upperArgList.Contains("HELP"))
            {
                OutputUsage();
                return(true);
            }

            enableVSTS = upperArgList.IndexOf("-VSTS") > -1 || upperArgList.IndexOf("-V") > -1;
            var warnOnUnprocessed = upperArgList.IndexOf("-WARN") > -1 || upperArgList.IndexOf("-W") > -1;

            TabularModelHandler h;

            if (args.Length == 2 || args[2].StartsWith("-"))
            {
                // File argument provided (either alone or with switches), i.e.:
                //      TabularEditor.exe myfile.bim
                //      TabularEditor.exe myfile.bim -...

                if (!File.Exists(args[1]) && !File.Exists(args[1] + "\\database.json"))
                {
                    Error("File not found: {0}", args[1]);
                    return(true);
                }
                else
                {
                    // If nothing else was specified on the command-line, open the UI:
                    if (args.Length == 2)
                    {
                        return(false);
                    }
                }

                try
                {
                    h = new TOMWrapper.TabularModelHandler(args[1]);
                }
                catch (Exception e)
                {
                    Error("Error loading file: " + e.Message);
                    return(true);
                }
            }
            else if (args.Length == 3 || args[3].StartsWith("-"))
            {
                // Server + Database argument provided (either alone or with switches), i.e.:
                //      TabularEditor.exe localhost AdventureWorks
                //      TabularEditor.exe localhost AdventureWorks -...
                // If nothing else was specified on the command-line, open the UI:
                if (args.Length == 3)
                {
                    return(false);
                }

                try
                {
                    h = new TOMWrapper.TabularModelHandler(args[1], args[2]);
                }
                catch (Exception e)
                {
                    Error("Error loading model: " + e.Message);
                    return(true);
                }
            }
            else
            {
                // Otherwise, it's nonsensical
                return(false);
            }

            string script     = null;
            string scriptFile = null;

            var doScript = upperArgList.IndexOf("-SCRIPT");

            if (doScript == -1)
            {
                doScript = upperArgList.IndexOf("-S");
            }
            if (doScript > -1)
            {
                if (upperArgList.Count <= doScript)
                {
                    Error("Invalid argument syntax.\n");
                    OutputUsage();
                    return(true);
                }
                scriptFile = argList[doScript + 1];
                if (!File.Exists(scriptFile))
                {
                    Error("Specified script file not found.\n");
                    return(true);
                }

                script = File.ReadAllText(scriptFile);
            }

            string buildOutputPath = null;

            var doSave = upperArgList.IndexOf("-BUILD");

            if (doSave == -1)
            {
                doSave = upperArgList.IndexOf("-B");
            }
            if (doSave > -1)
            {
                if (upperArgList.Count <= doSave)
                {
                    Error("Invalid argument syntax.\n");
                    OutputUsage();
                    return(true);
                }
                buildOutputPath = argList[doSave + 1];
                var directoryName = new FileInfo(buildOutputPath).Directory.FullName;
                Directory.CreateDirectory(directoryName);
            }

            // Load model:
            cw.WriteLine("Loading model...");

            if (!string.IsNullOrEmpty(script))
            {
                cw.WriteLine("Executing script...");

                System.CodeDom.Compiler.CompilerResults result;
                Scripting.ScriptOutputForm.Reset(false);
                var dyn = ScriptEngine.CompileScript(script, out result);
                if (result.Errors.Count > 0)
                {
                    cw.WriteLine("Script compilation errors:");
                    foreach (System.CodeDom.Compiler.CompilerError err in result.Errors)
                    {
                        ErrorX(err.ErrorText, scriptFile, err.Line, err.Column, err.ErrorNumber);
                    }
                    return(true);
                }
                try
                {
                    dyn.Invoke(h.Model, null);
                }
                catch (Exception ex)
                {
                    Error("Script execution error: " + ex.Message);
                    return(true);
                }
            }

            if (!string.IsNullOrEmpty(buildOutputPath))
            {
                cw.WriteLine("Building Model.bim file...");
                h.Save(buildOutputPath, SaveFormat.ModelSchemaOnly, SerializeOptions.Default);
            }

            var replaceMap = new Dictionary <string, string>();

            var analyze = upperArgList.IndexOf("-ANALYZE");

            if (analyze == -1)
            {
                analyze = upperArgList.IndexOf("-A");
            }
            if (analyze > -1)
            {
                var rulefile = argList.Skip(analyze + 1).FirstOrDefault(n => !n.StartsWith("-"));

                var analyzer = new BPA.Analyzer()
                {
                    Model = h.Model
                };

                BPA.BestPracticeCollection suppliedRules = null;
                if (!string.IsNullOrEmpty(rulefile))
                {
                    if (!File.Exists(rulefile))
                    {
                        Error("Rulefile not found: {0}", rulefile);
                        return(true);
                    }
                    try
                    {
                        suppliedRules = BPA.BestPracticeCollection.LoadFromJsonFile(rulefile);
                    }
                    catch
                    {
                        Error("Invalid rulefile: {0}", rulefile);
                        return(true);
                    }
                }

                cw.WriteLine("Running Best Practice Analyzer...");
                cw.WriteLine("=================================");
                IEnumerable <BPA.AnalyzerResult> bpaResults;
                if (suppliedRules == null)
                {
                    bpaResults = analyzer.AnalyzeAll();
                }
                else
                {
                    bpaResults = analyzer.Analyze(suppliedRules.Concat(analyzer.LocalRules));
                }

                if (!bpaResults.Any())
                {
                    cw.WriteLine("No objects in violation of Best Practices.");
                }


                foreach (var res in bpaResults)
                {
                    if (res.RuleHasError)
                    {
                        Warning("Error on rule '{0}': {1}", res.RuleName, res.RuleError);
                    }
                    else
                    {
                        var text = string.Format("{0} {1} violates rule \"{2}\"",
                                                 res.Object.GetTypeName(),
                                                 (res.Object as IDaxObject)?.DaxObjectFullName ?? res.ObjectName,
                                                 res.RuleName
                                                 );
                        if (res.Rule.Severity <= 1)
                        {
                            cw.WriteLine(text);
                        }
                        else if (res.Rule.Severity == 2)
                        {
                            Warning(text);
                        }
                        else if (res.Rule.Severity >= 3)
                        {
                            Error(text);
                        }
                    }
                }
                cw.WriteLine("=================================");
            }

            var deploy = upperArgList.IndexOf("-DEPLOY");

            if (deploy == -1)
            {
                deploy = upperArgList.IndexOf("-D");
            }
            if (deploy > -1)
            {
                var serverName = argList.Skip(deploy + 1).FirstOrDefault(); if (serverName != null && serverName.StartsWith("-"))
                {
                    serverName = null;
                }
                var databaseID = argList.Skip(deploy + 2).FirstOrDefault(); if (databaseID != null && databaseID.StartsWith("-"))
                {
                    databaseID = null;
                }

                var conn = upperArgList.IndexOf("-CONNECTIONS");
                if (conn == -1)
                {
                    conn = upperArgList.IndexOf("-C");
                }
                if (conn > -1)
                {
                    var replaces = argList.Skip(conn + 1).TakeWhile(s => s[0] != '-').ToList();

                    if (replaces.Count > 0 && replaces.Count % 2 == 0)
                    {
                        // Placeholder replacing:
                        for (var index = 0; index < replaces.Count; index = index + 2)
                        {
                            replaceMap.Add(replaces[index], replaces[index + 1]);
                        }
                    }
                }

                string userName = null;
                string password = null;
                var    options  = DeploymentOptions.StructureOnly;

                var switches = args.Skip(deploy + 1).Where(arg => arg.StartsWith("-")).Select(arg => arg.ToUpper()).ToList();

                if (string.IsNullOrEmpty(serverName) || string.IsNullOrEmpty(databaseID))
                {
                    Error("Invalid argument syntax.\n");
                    OutputUsage();
                    return(true);
                }
                if (switches.Contains("-L") || switches.Contains("-LOGIN"))
                {
                    var switchPos = upperArgList.IndexOf("-LOGIN"); if (switchPos == -1)
                    {
                        switchPos = upperArgList.IndexOf("-L");
                    }
                    userName = argList.Skip(switchPos + 1).FirstOrDefault(); if (userName != null && userName.StartsWith("-"))
                    {
                        userName = null;
                    }
                    password = argList.Skip(switchPos + 2).FirstOrDefault(); if (password != null && password.StartsWith("-"))
                    {
                        password = null;
                    }
                    if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
                    {
                        Error("Missing username or password.\n");
                        OutputUsage();
                        return(true);
                    }
                    switches.Remove("-L"); switches.Remove("-LOGIN");
                }
                if (switches.Contains("-O") || switches.Contains("-OVERWRITE"))
                {
                    options.DeployMode = DeploymentMode.CreateOrAlter;
                    switches.Remove("-O"); switches.Remove("-OVERWRITE");
                }
                else
                {
                    options.DeployMode = DeploymentMode.CreateDatabase;
                }
                if (switches.Contains("-P") || switches.Contains("-PARTITIONS"))
                {
                    options.DeployPartitions = true;
                    switches.Remove("-P"); switches.Remove("-PARTITIONS");
                }
                if (switches.Contains("-C") || switches.Contains("-CONNECTIONS"))
                {
                    options.DeployConnections = true;
                    switches.Remove("-C"); switches.Remove("-CONNECTIONS");
                }
                if (switches.Contains("-R") || switches.Contains("-ROLES"))
                {
                    options.DeployRoles = true;
                    switches.Remove("-R"); switches.Remove("-ROLES");

                    if (switches.Contains("-M") || switches.Contains("-MEMBERS"))
                    {
                        options.DeployRoleMembers = true;
                        switches.Remove("-M"); switches.Remove("-MEMBERS");
                    }
                }

                /*if(switches.Count > 0)
                 * {
                 *  Error("Unknown switch {0}\n", switches[0]);
                 *  OutputUsage();
                 *  return true;
                 * }*/

                try
                {
                    if (replaceMap.Count > 0)
                    {
                        cw.WriteLine("Switching connection string placeholders...");
                        foreach (var map in replaceMap)
                        {
                            h.Model.DataSources.SetPlaceholder(map.Key, map.Value);
                        }
                    }

                    cw.WriteLine("Deploying...");
                    var cs = string.IsNullOrEmpty(userName) ? TabularConnection.GetConnectionString(serverName) :
                             TabularConnection.GetConnectionString(serverName, userName, password);
                    var deploymentResult = TabularDeployer.Deploy(h, cs, databaseID, options);
                    cw.WriteLine("Deployment succeeded.");
                    foreach (var err in deploymentResult.Issues)
                    {
                        Issue(err);
                    }
                    foreach (var err in deploymentResult.Warnings)
                    {
                        Warning(err);
                    }
                    foreach (var err in deploymentResult.Unprocessed)
                    {
                        if (warnOnUnprocessed)
                        {
                            Warning(err);
                        }
                        else
                        {
                            cw.WriteLine(err);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Error("Deployment failed! " + ex.Message);
                }
                return(true);
            }

            return(true);
        }