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(); } }
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!"; } }
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(); } }
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"); }
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(); } }
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)); }
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(); } }
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(); }
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!"; } }
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); }
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); }
public void SetupTomwrapperTest() { var handler = new TabularModelHandler(@"TestData\AdventureWorks.bim"); TabularDeployer.Deploy(handler, Constants.ServerName, "TomWrapperTest"); }
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)); }
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); }