This commit is contained in:
Christian Wade 2019-12-30 17:14:29 -08:00
parent bfcc869d19
commit 353bab30c5
10 changed files with 180 additions and 27 deletions

View File

@ -194,18 +194,10 @@ namespace AlmToolkit
btnGenerateScript.Enabled = true;
_compareState = CompareState.Validated;
// This method needs to be moved out of comparison control during clean up
//ComparisonCtrl.SetValidatedState();
}
private bool ShowConnectionsForm()
{
//if (ComparisonCtrl.CompareState != CompareState.NotCompared)
//{
//
// ComparisonCtrl.RefreshSkipSelections();
//}
if (_compareState != CompareState.NotCompared)
{
//just in case user has some selections, store them to the SkipSelections collection
@ -672,7 +664,7 @@ namespace AlmToolkit
private void btnUpdate_Click(object sender, EventArgs e)
{
if (MessageBox.Show($"Are you sure you want to update target?", Utils.AssemblyProduct, MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
if (MessageBox.Show($"Are you sure you want to update the target?", Utils.AssemblyProduct, MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
{
return;
}

View File

@ -210,6 +210,7 @@
</Reference>
<Reference Include="System.DirectoryServices.AccountManagement" />
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Management" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Runtime.Caching" />
@ -230,6 +231,7 @@
<Compile Include="TabularCompare\Enums.cs" />
<Compile Include="TabularCompare\BlobKeyEventArgs.cs" />
<Compile Include="TabularCompare\PasswordPromptEventArgs.cs" />
<Compile Include="TabularCompare\PowerBiTemplate.cs" />
<Compile Include="TabularCompare\TabularMetadata\CalculationItem.cs" />
<Compile Include="TabularCompare\TabularMetadata\CalculationItemCollection.cs" />
<Compile Include="TabularCompare\TabularMetadata\Model.cs" />
@ -250,10 +252,10 @@
<Compile Include="TabularCompare\UI\Connections.Designer.cs">
<DependentUpon>Connections.cs</DependentUpon>
</Compile>
<Compile Include="TabularCompare\UI\DesktopInstances\ManagedIpHelper.cs" />
<Compile Include="TabularCompare\UI\DesktopInstances\PowerBIHelper.cs" />
<Compile Include="TabularCompare\UI\DesktopInstances\ProcessExtensions.cs" />
<Compile Include="TabularCompare\UI\DesktopInstances\WindowTitle.cs" />
<Compile Include="TabularCompare\DesktopInstances\ManagedIpHelper.cs" />
<Compile Include="TabularCompare\DesktopInstances\PowerBIHelper.cs" />
<Compile Include="TabularCompare\DesktopInstances\ProcessExtensions.cs" />
<Compile Include="TabularCompare\DesktopInstances\WindowTitle.cs" />
<Compile Include="TabularCompare\UI\Utils.cs" />
<Compile Include="TabularCompare\UI\BlobCredentials.cs">
<SubType>Form</SubType>

View File

@ -451,7 +451,7 @@ namespace BismNormalizer.TabularCompare
bool exceptionLoadingFile = false;
try
{
tomDatabase = TOM.JsonSerializer.DeserializeDatabase(File.ReadAllText(_bimFile));
tomDatabase = OpenDatabaseFromFile();
}
catch
{
@ -497,7 +497,7 @@ namespace BismNormalizer.TabularCompare
}
}
Server amoServer = new Server();
Microsoft.AnalysisServices.Server amoServer = new Microsoft.AnalysisServices.Server();
try
{
amoServer.Connect(BuildConnectionString());
@ -546,7 +546,7 @@ namespace BismNormalizer.TabularCompare
throw new ConnectionException($"Analysis Server {this.ServerName} is not running in Tabular mode");
}
Database amoDatabase = null;
Microsoft.AnalysisServices.Database amoDatabase = null;
if (this.DatabaseName == "" && this.ServerName.ToUpper().StartsWith("localhost:".ToUpper()))
{
//PBI Desktop doesn't have db name yet
@ -700,6 +700,27 @@ $@"{{
amoDatabase.DirectQueryMode == DirectQueryMode.DirectQuery || amoDatabase.DirectQueryMode == DirectQueryMode.InMemoryWithDirectQuery || amoDatabase.DirectQueryMode == DirectQueryMode.DirectQueryWithInMemory);
}
/// <summary>
/// Check if file is PBIT and return instantiated TOM database.
/// </summary>
/// <returns></returns>
public TOM.Database OpenDatabaseFromFile()
{
TOM.Database tomDatabase;
string modelJson;
if (_bimFile.ToUpper().EndsWith(".PBIT"))
{
PowerBiTemplate pbit = new PowerBiTemplate(_bimFile);
modelJson = pbit.ModelJson;
}
else
{
modelJson = File.ReadAllText(_bimFile);
}
tomDatabase = TOM.JsonSerializer.DeserializeDatabase(modelJson);
return tomDatabase;
}
/// <summary>
/// Build connection string.
/// </summary>

View File

@ -6,6 +6,7 @@ using System.Net;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
//namespace DaxStudio.UI.Utils
namespace BismNormalizer.TabularCompare.UI.DesktopInstances
{

View File

@ -4,6 +4,7 @@ using System.Diagnostics;
//using Serilog;
using System.Security.Principal;
//namespace DaxStudio.UI.Utils
namespace BismNormalizer.TabularCompare.UI.DesktopInstances
{
public enum EmbeddedSSASIcon

View File

@ -2,6 +2,7 @@
using System.Linq;
using System.Management;
//namespace DaxStudio.UI.Extensions
namespace BismNormalizer.TabularCompare.UI.DesktopInstances
{
public static class ProcessExtensions

View File

@ -6,6 +6,7 @@ using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
//namespace DaxStudio.Common
namespace BismNormalizer.TabularCompare.UI.DesktopInstances
{
public class WindowTitle

View File

@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//namespace TabularEditor.TOMWrapper.PowerBI
namespace BismNormalizer.TabularCompare
{
/// <summary>
/// Represents a Power BI Template (.pbit) file. Constructor loads the file into memory. Provides properties for
/// getting and setting the data model json, as well as saving the content back to a .pbit file.
/// </summary>
internal class PowerBiTemplate
{
MemoryStream fileData = new MemoryStream();
public PowerBiTemplate(string path)
{
try
{
using (var fs = new FileStream(path, FileMode.Open))
{
fs.CopyTo(fileData);
fileData.Seek(0, SeekOrigin.Begin);
using (var za = new ZipArchive(fileData, ZipArchiveMode.Read, true))
{
var modelEntry = za.Entries.FirstOrDefault(e => e.Name == "DataModelSchema");
if (modelEntry != null)
{
using (var sr = new StreamReader(modelEntry.Open(), Encoding.Unicode, true, 1024, true))
{
_modelJson = sr.ReadToEnd();
}
}
else
throw new Exception();
}
}
}
catch
{
throw new InvalidOperationException("This file is not a valid PBIX / PBIT file.");
}
}
private string _modelJson;
public string ModelJson
{
get
{
return _modelJson;
}
set
{
SetModelJson(value);
_modelJson = value;
}
}
private void SetModelJson(string modelJson)
{
try
{
fileData.Seek(0, SeekOrigin.Begin);
using (var za = new ZipArchive(fileData, ZipArchiveMode.Update, true))
{
var modelEntry = za.Entries.FirstOrDefault(e => e.Name == "DataModelSchema");
if (modelEntry != null)
{
var modelEntryName = modelEntry.FullName;
modelEntry.Delete();
modelEntry = za.CreateEntry(modelEntryName);
var unicodeNoBom = new UnicodeEncoding(false, false);
using (var sw = new StreamWriter(modelEntry.Open(), unicodeNoBom, 1024, true))
{
sw.Write(modelJson);
}
}
else
throw new Exception();
}
}
catch
{
throw new InvalidOperationException("This file is not a valid PBIX / PBIT file.");
}
}
public void SaveAs(string path)
{
fileData.Seek(0, SeekOrigin.Begin);
using (var fs = File.Open(path, FileMode.OpenOrCreate, FileAccess.Write))
{
fs.SetLength(0);
fileData.CopyTo(fs);
}
}
}
}

View File

@ -59,7 +59,7 @@ namespace BismNormalizer.TabularCompare.TabularMetadata
if (_connectionInfo.UseBimFile)
{
_database = JsonSerializer.DeserializeDatabase(File.ReadAllText(_connectionInfo.BimFile));
_database = _connectionInfo.OpenDatabaseFromFile();
}
else
{
@ -1767,22 +1767,45 @@ namespace BismNormalizer.TabularCompare.TabularMetadata
//serialize db to json
SerializeOptions options = new SerializeOptions();
bool isPbit = (_connectionInfo.UseBimFile && _connectionInfo.BimFile.ToUpper().EndsWith(".PBIT"));
if (isPbit)
{
options.IgnoreInferredProperties = false;
options.IgnoreInferredObjects = false;
options.IgnoreTimestamps = false;
}
else
{
options.IgnoreInferredProperties = true;
options.IgnoreInferredObjects = true;
options.IgnoreTimestamps = true;
}
options.SplitMultilineStrings = true;
string json = JsonSerializer.SerializeDatabase(_database, options);
//replace db name with "SemanticModel"
if (!isPbit)
{
JObject jDb = JObject.Parse(json);
jDb["name"] = "SemanticModel";
jDb["id"] = "SemanticModel";
json = jDb.ToString();
}
if (_connectionInfo.UseBimFile)
{
if (isPbit)
{
PowerBiTemplate pbit = new PowerBiTemplate(_connectionInfo.BimFile);
pbit.ModelJson = json;
pbit.SaveAs(_connectionInfo.BimFile);
}
else
{
File.WriteAllText(_connectionInfo.BimFile, json);
}
}
else
{
File.WriteAllText(_connectionInfo.SsdtBimFile, json);
@ -2153,7 +2176,7 @@ namespace BismNormalizer.TabularCompare.TabularMetadata
//script db to json
string json = JsonScripter.ScriptCreateOrReplace(_database);
if (_connectionInfo.UseProject)
if (_connectionInfo.UseProject || _connectionInfo.UseBimFile)
{
//replace db/cube name/id with name of deploymnet db from the project file
JObject jScript = JObject.Parse(json);
@ -2164,6 +2187,16 @@ namespace BismNormalizer.TabularCompare.TabularMetadata
((JObject)createOrReplace["database"])["name"] = _connectionInfo.DeploymentServerDatabase;
((JObject)createOrReplace["database"])["id"] = _connectionInfo.DeploymentServerDatabase;
}
else if (_connectionInfo.UseBimFile)
{
try
{
string fileName = Path.GetFileNameWithoutExtension(_connectionInfo.BimFile);
((JObject)createOrReplace["object"])["database"] = fileName;
((JObject)createOrReplace["database"])["name"] = fileName;
}
catch { }
}
json = jScript.ToString();
}

View File

@ -492,7 +492,7 @@ namespace BismNormalizer.TabularCompare.UI
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.InitialDirectory = (String.IsNullOrEmpty(Settings.Default.LastBimFileLocation) ? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) : Settings.Default.LastBimFileLocation);
ofd.Filter = "BIM Files (.bim)|*.bim|All files (*.*)|*.*";
ofd.Filter = "PBIT files (.pbit)|*.pbit|BIM files (.bim)|*.bim|All files (*.*)|*.*";
ofd.Title = "Open";
return ofd;
}