├── .gitattributes ├── .gitignore ├── LICENSE ├── MetaCube.sln ├── MetaCube ├── App.config ├── Classes │ ├── SSASAMO.cs │ └── SSASObject.cs ├── Form1.Designer.cs ├── Form1.cs ├── Form1.resx ├── MetaCube.csproj ├── Program.cs └── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | [Ss]tyle[Cc]op.* 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.pfx 190 | *.publishsettings 191 | node_modules/ 192 | orleans.codegen.cs 193 | 194 | # RIA/Silverlight projects 195 | Generated_Code/ 196 | 197 | # Backup & report files from converting an old project file 198 | # to a newer Visual Studio version. Backup files are not needed, 199 | # because we have git ;-) 200 | _UpgradeReport_Files/ 201 | Backup*/ 202 | UpgradeLog*.XML 203 | UpgradeLog*.htm 204 | 205 | # SQL Server files 206 | *.mdf 207 | *.ldf 208 | 209 | # Business Intelligence projects 210 | *.rdl.data 211 | *.bim.layout 212 | *.bim_*.settings 213 | 214 | # Microsoft Fakes 215 | FakesAssemblies/ 216 | 217 | # GhostDoc plugin setting file 218 | *.GhostDoc.xml 219 | 220 | # Node.js Tools for Visual Studio 221 | .ntvs_analysis.dat 222 | 223 | # Visual Studio 6 build log 224 | *.plg 225 | 226 | # Visual Studio 6 workspace options file 227 | *.opt 228 | 229 | # Visual Studio LightSwitch build output 230 | **/*.HTMLClient/GeneratedArtifacts 231 | **/*.DesktopClient/GeneratedArtifacts 232 | **/*.DesktopClient/ModelManifest.xml 233 | **/*.Server/GeneratedArtifacts 234 | **/*.Server/ModelManifest.xml 235 | _Pvt_Extensions 236 | 237 | # LightSwitch generated files 238 | GeneratedArtifacts/ 239 | ModelManifest.xml 240 | 241 | # Paket dependency manager 242 | .paket/paket.exe 243 | 244 | # FAKE - F# Make 245 | .fake/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Hadi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MetaCube.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.40629.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetaCube", "MetaCube\MetaCube.csproj", "{CA89E548-2038-4F5B-8E28-29EC839D6339}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {CA89E548-2038-4F5B-8E28-29EC839D6339}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {CA89E548-2038-4F5B-8E28-29EC839D6339}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {CA89E548-2038-4F5B-8E28-29EC839D6339}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {CA89E548-2038-4F5B-8E28-29EC839D6339}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /MetaCube/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /MetaCube/Classes/SSASAMO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Microsoft.AnalysisServices; 6 | using Microsoft.AnalysisServices.Hosting; 7 | 8 | namespace MetaCube 9 | { 10 | public static class SSASAMO 11 | { 12 | public static List ReadMeta(string ServerName) 13 | { 14 | try 15 | { 16 | 17 | List result = new List(); 18 | 19 | String ConnStr; 20 | 21 | DateTime? dt = null; 22 | int idx = 0; 23 | int DbID = 0; 24 | int CubeID = 0; 25 | int ObjectID = 0; 26 | 27 | string DataDir; 28 | string OLAPServerName = ServerName; 29 | 30 | ConnStr = "Provider=MSOLAP;Data Source=" + OLAPServerName + ";"; 31 | 32 | Server OLAPServer = new Server(); 33 | OLAPServer.Connect(ConnStr); 34 | 35 | DataDir = OLAPServer.ServerProperties["DataDir"].Value; 36 | 37 | string[] DatabasesDir = System.IO.Directory.GetDirectories(DataDir, "*", System.IO.SearchOption.TopDirectoryOnly); 38 | string[] DatabasesFiles = System.IO.Directory.GetFiles(DataDir, "*", System.IO.SearchOption.TopDirectoryOnly); 39 | 40 | result.Add(new SSASObject 41 | { 42 | ID = idx, 43 | ParentID = null, 44 | FolderModifiedDate = System.IO.Directory.GetLastWriteTime(DataDir), 45 | FolderPath = DataDir, 46 | ObjectName = OLAPServerName, 47 | Type = SSASObject.ObjectType.Server 48 | }); 49 | 50 | // Database 51 | foreach (Database OLAPDatabase in OLAPServer.Databases) 52 | { 53 | 54 | 55 | string CurrentDbDir = DatabasesDir.Where(x => x.StartsWith(DataDir + "\\" + OLAPDatabase.ID.ToString() + ".") && x.EndsWith(".db")).DefaultIfEmpty("").First(); 56 | string CurrentDbXmlFile = DatabasesFiles.Where(x => x.StartsWith(DataDir + "\\" + OLAPDatabase.ID.ToString() + ".") && x.EndsWith(".db.xml")).DefaultIfEmpty("").First(); 57 | 58 | string[] DbObjectsDir = System.IO.Directory.GetDirectories(CurrentDbDir, "*", System.IO.SearchOption.TopDirectoryOnly); 59 | string[] DbObjectsFiles = System.IO.Directory.GetFiles(CurrentDbDir, "*", System.IO.SearchOption.TopDirectoryOnly); 60 | 61 | 62 | idx++; 63 | DbID = idx; 64 | result.Add(new SSASObject 65 | { 66 | ID = idx, 67 | ParentID = 0, 68 | ObjectID = OLAPDatabase.ID, 69 | FolderModifiedDate = CurrentDbDir == "" ? dt : System.IO.Directory.GetLastWriteTime(CurrentDbDir), 70 | XmlIncremetalID = System.IO.Path.GetFileNameWithoutExtension( 71 | System.IO.Path.GetFileNameWithoutExtension(CurrentDbXmlFile)).Substring( 72 | System.IO.Path.GetFileNameWithoutExtension(CurrentDbXmlFile).IndexOf(".") + 1), 73 | Extension = ".db", 74 | FolderName = System.IO.Path.GetFileName(CurrentDbDir), 75 | FolderPath = CurrentDbDir, 76 | ObjectName = OLAPDatabase.Name, 77 | Type = SSASObject.ObjectType.Database, 78 | XMLFileName = System.IO.Path.GetFileName(CurrentDbXmlFile), 79 | XMLFilePath = CurrentDbXmlFile, 80 | XmlModifiedDate = CurrentDbXmlFile == "" ? dt : System.IO.File.GetLastWriteTime(CurrentDbXmlFile), 81 | FolderIncremetalID = System.IO.Path.GetFileNameWithoutExtension(CurrentDbDir).Substring( 82 | System.IO.Path.GetFileNameWithoutExtension(CurrentDbDir).IndexOf(".") + 1) 83 | }); 84 | 85 | 86 | 87 | //Data Source 88 | foreach (DataSource OLAPDataSource in OLAPDatabase.DataSources) 89 | { 90 | idx++; 91 | string CurrentDataSourceDir = DbObjectsDir.Where(x => x.StartsWith(CurrentDbDir + "\\" + OLAPDataSource.ID.ToString() + ".") && x.EndsWith(".ds")).DefaultIfEmpty("").First(); 92 | string CurrentDataSourceXmlFile = DbObjectsFiles.Where(x => x.StartsWith(CurrentDbDir + "\\" + OLAPDataSource.ID.ToString() + ".") && x.EndsWith(".ds.xml")).DefaultIfEmpty("").First(); 93 | result.Add(new SSASObject 94 | { 95 | ID = idx, 96 | ParentID = DbID, 97 | ObjectID = OLAPDataSource.ID, 98 | FolderModifiedDate = CurrentDataSourceDir == "" ? dt : System.IO.Directory.GetLastWriteTime(CurrentDataSourceDir), 99 | XmlIncremetalID = System.IO.Path.GetFileNameWithoutExtension( 100 | System.IO.Path.GetFileNameWithoutExtension(CurrentDataSourceXmlFile)).Substring( 101 | System.IO.Path.GetFileNameWithoutExtension(CurrentDataSourceXmlFile).IndexOf(".") + 1), 102 | Extension = ".ds", 103 | FolderName = System.IO.Path.GetFileName(CurrentDataSourceDir), 104 | FolderPath = CurrentDbDir, 105 | ObjectName = OLAPDataSource.Name, 106 | Type = SSASObject.ObjectType.DataSource, 107 | XMLFileName = System.IO.Path.GetFileName(CurrentDataSourceXmlFile), 108 | XMLFilePath = CurrentDataSourceXmlFile, 109 | XmlModifiedDate = CurrentDataSourceXmlFile == "" ? dt : System.IO.File.GetLastWriteTime(CurrentDataSourceXmlFile), 110 | FolderIncremetalID = System.IO.Path.GetFileNameWithoutExtension(CurrentDataSourceDir).Substring( 111 | System.IO.Path.GetFileNameWithoutExtension(CurrentDataSourceDir).IndexOf(".") + 1) 112 | }); 113 | 114 | 115 | } 116 | 117 | //Data Source View 118 | foreach (DataSourceView OLAPDataSourceView in OLAPDatabase.DataSourceViews) 119 | { 120 | idx++; 121 | string CurrentDataSourceViewDir = DbObjectsDir.Where(x => x.StartsWith(CurrentDbDir + "\\" + OLAPDataSourceView.ID.ToString() + ".") && x.EndsWith(".dsv")).DefaultIfEmpty("").First(); 122 | string CurrentDataSourceViewXmlFile = DbObjectsFiles.Where(x => x.StartsWith(CurrentDbDir + "\\" + OLAPDataSourceView.ID.ToString() + ".") && x.EndsWith(".dsv.xml")).DefaultIfEmpty("").First(); 123 | result.Add(new SSASObject 124 | { 125 | ID = idx, 126 | ParentID = DbID, 127 | ObjectID = OLAPDataSourceView.ID, 128 | FolderModifiedDate = CurrentDataSourceViewDir == "" ? dt : System.IO.Directory.GetLastWriteTime(CurrentDataSourceViewDir), 129 | XmlIncremetalID = System.IO.Path.GetFileNameWithoutExtension( 130 | System.IO.Path.GetFileNameWithoutExtension(CurrentDataSourceViewXmlFile)).Substring( 131 | System.IO.Path.GetFileNameWithoutExtension(CurrentDataSourceViewXmlFile).IndexOf(".") + 1), 132 | Extension = ".dsv", 133 | FolderName = System.IO.Path.GetFileName(CurrentDataSourceViewDir), 134 | FolderPath = CurrentDbDir, 135 | ObjectName = OLAPDataSourceView.Name, 136 | Type = SSASObject.ObjectType.DataSourceView, 137 | XMLFileName = System.IO.Path.GetFileName(CurrentDataSourceViewXmlFile), 138 | XMLFilePath = CurrentDataSourceViewXmlFile, 139 | XmlModifiedDate = CurrentDataSourceViewXmlFile == "" ? dt : System.IO.File.GetLastWriteTime(CurrentDataSourceViewXmlFile), 140 | FolderIncremetalID = System.IO.Path.GetFileNameWithoutExtension(CurrentDataSourceViewDir).Substring( 141 | System.IO.Path.GetFileNameWithoutExtension(CurrentDataSourceViewDir).IndexOf(".") + 1) 142 | }); 143 | 144 | 145 | } 146 | 147 | 148 | //Dimension 149 | foreach (Dimension OLAPDimension in OLAPDatabase.Dimensions) 150 | { 151 | 152 | idx++; 153 | string DimensionDir = DbObjectsDir.Where(x => x.StartsWith(CurrentDbDir + "\\" + OLAPDimension.ID.ToString() + ".") && x.EndsWith(".dim")).DefaultIfEmpty("").First(); 154 | string DimensionXmlFile = DbObjectsFiles.Where(x => x.StartsWith(CurrentDbDir + "\\" + OLAPDimension.ID.ToString() + ".") && x.EndsWith(".dim.xml")).DefaultIfEmpty("").First(); 155 | 156 | result.Add(new SSASObject 157 | { 158 | ID = idx, 159 | ParentID = DbID, 160 | ObjectID = OLAPDimension.ID, 161 | FolderModifiedDate = DimensionDir == "" ? dt : System.IO.Directory.GetLastWriteTime(DimensionDir), 162 | XmlIncremetalID = System.IO.Path.GetFileNameWithoutExtension( 163 | System.IO.Path.GetFileNameWithoutExtension(DimensionXmlFile)).Substring( 164 | System.IO.Path.GetFileNameWithoutExtension(DimensionXmlFile).IndexOf(".") + 1), 165 | Extension = ".dim", 166 | FolderName = System.IO.Path.GetFileName(DimensionDir), 167 | FolderPath = DimensionDir, 168 | ObjectName = OLAPDimension.Name, 169 | Type = SSASObject.ObjectType.Dimension, 170 | XMLFileName = System.IO.Path.GetFileName(DimensionXmlFile), 171 | XMLFilePath = DimensionXmlFile, 172 | XmlModifiedDate = DimensionXmlFile == "" ? dt : System.IO.File.GetLastWriteTime(DimensionXmlFile), 173 | FolderIncremetalID = System.IO.Path.GetFileNameWithoutExtension(DimensionDir).Substring( 174 | System.IO.Path.GetFileNameWithoutExtension(DimensionDir).IndexOf(".") + 1) 175 | }); 176 | } 177 | 178 | // Cube 179 | foreach (Cube OLAPCubex in OLAPDatabase.Cubes) 180 | { 181 | 182 | 183 | idx++; 184 | CubeID = idx; 185 | 186 | string CubeDir = DbObjectsDir.Where(x => x.StartsWith(CurrentDbDir + "\\" + OLAPCubex.ID.ToString() + ".") && x.EndsWith(".cub")).DefaultIfEmpty("").First(); 187 | string CubeXmlFile = DbObjectsFiles.Where(x => x.StartsWith(CurrentDbDir + "\\" + OLAPCubex.ID.ToString() + ".") && x.EndsWith(".cub.xml")).DefaultIfEmpty("").First(); 188 | 189 | string[] CubeMeasureGroupsDir = System.IO.Directory.GetDirectories(CubeDir, "*", System.IO.SearchOption.TopDirectoryOnly); 190 | string[] CubeMeasureGroupsFiles = System.IO.Directory.GetFiles(CubeDir, "*", System.IO.SearchOption.TopDirectoryOnly); 191 | 192 | 193 | result.Add(new SSASObject 194 | { 195 | ID = idx, 196 | ParentID = DbID, 197 | ObjectID = OLAPCubex.ID, 198 | FolderModifiedDate = CubeDir == "" ? dt : System.IO.Directory.GetLastWriteTime(CubeDir), 199 | XmlIncremetalID = System.IO.Path.GetFileNameWithoutExtension( 200 | System.IO.Path.GetFileNameWithoutExtension(CubeXmlFile)).Substring( 201 | System.IO.Path.GetFileNameWithoutExtension(CubeXmlFile).IndexOf(".") + 1), 202 | Extension = ".cub", 203 | FolderName = System.IO.Path.GetFileName(CubeDir), 204 | FolderPath = CubeDir, 205 | ObjectName = OLAPCubex.Name, 206 | Type = SSASObject.ObjectType.Cube, 207 | XMLFileName = System.IO.Path.GetFileName(CubeXmlFile), 208 | XMLFilePath = CubeXmlFile, 209 | XmlModifiedDate = CubeXmlFile == "" ? dt : System.IO.File.GetLastWriteTime(CubeXmlFile), 210 | FolderIncremetalID = System.IO.Path.GetFileNameWithoutExtension(CubeDir).Substring( 211 | System.IO.Path.GetFileNameWithoutExtension(CubeDir).IndexOf(".") + 1) 212 | }); 213 | 214 | //Measure Group 215 | foreach (MeasureGroup OLAPMeasureGroup in OLAPCubex.MeasureGroups) 216 | { 217 | 218 | idx++; 219 | ObjectID = idx; 220 | string MeasureGroupDir = CubeMeasureGroupsDir.Where(x => x.StartsWith(CubeDir + "\\" + OLAPMeasureGroup.ID.ToString() + ".") && x.EndsWith(".det")).DefaultIfEmpty("").First(); 221 | string MeasureGroupXmlFile = CubeMeasureGroupsFiles.Where(x => x.StartsWith(CubeDir + "\\" + OLAPMeasureGroup.ID.ToString() + ".") && x.EndsWith(".det.xml")).DefaultIfEmpty("").First(); 222 | 223 | string[] GroupPartitionDir = System.IO.Directory.GetDirectories(MeasureGroupDir, "*", System.IO.SearchOption.TopDirectoryOnly); 224 | string[] GroupPartitionFiles = System.IO.Directory.GetFiles(MeasureGroupDir, "*", System.IO.SearchOption.TopDirectoryOnly); 225 | 226 | result.Add(new SSASObject 227 | { 228 | ID = idx, 229 | ParentID = CubeID, 230 | ObjectID = OLAPMeasureGroup.ID, 231 | FolderModifiedDate = MeasureGroupDir == "" ? dt : System.IO.Directory.GetLastWriteTime(MeasureGroupDir), 232 | XmlIncremetalID = System.IO.Path.GetFileNameWithoutExtension( 233 | System.IO.Path.GetFileNameWithoutExtension(MeasureGroupXmlFile)).Substring( 234 | System.IO.Path.GetFileNameWithoutExtension(MeasureGroupXmlFile).IndexOf(".") + 1), 235 | Extension = ".det", 236 | FolderName = System.IO.Path.GetFileName(MeasureGroupDir), 237 | FolderPath = MeasureGroupDir, 238 | ObjectName = OLAPMeasureGroup.Name, 239 | Type = SSASObject.ObjectType.MeasureGroup, 240 | XMLFileName = System.IO.Path.GetFileName(MeasureGroupXmlFile), 241 | XMLFilePath = MeasureGroupXmlFile, 242 | XmlModifiedDate = MeasureGroupXmlFile == "" ? dt : System.IO.File.GetLastWriteTime(MeasureGroupXmlFile), 243 | FolderIncremetalID = System.IO.Path.GetFileNameWithoutExtension(MeasureGroupDir).Substring( 244 | System.IO.Path.GetFileNameWithoutExtension(MeasureGroupDir).IndexOf(".") + 1) 245 | }); 246 | 247 | //Aggregations 248 | foreach (AggregationDesign OLAPAggregationDesign in OLAPMeasureGroup.AggregationDesigns) 249 | { 250 | 251 | string AggregationDir = GroupPartitionDir.Where(x => x.StartsWith(MeasureGroupDir + "\\" + OLAPAggregationDesign.ID.ToString() + ".") && x.EndsWith(".agg")).DefaultIfEmpty("").First(); 252 | string AggregationXmlFile = GroupPartitionFiles.Where(x => x.StartsWith(MeasureGroupDir + "\\" + OLAPAggregationDesign.ID.ToString() + ".") && x.EndsWith(".agg.xml")).DefaultIfEmpty("").First(); 253 | 254 | idx++; 255 | 256 | result.Add(new SSASObject 257 | { 258 | ID = idx, 259 | ParentID = ObjectID, 260 | ObjectID = OLAPAggregationDesign.ID, 261 | FolderModifiedDate = AggregationDir == "" ? dt : System.IO.Directory.GetLastWriteTime(AggregationDir), 262 | XmlIncremetalID = System.IO.Path.GetFileNameWithoutExtension( 263 | System.IO.Path.GetFileNameWithoutExtension(AggregationXmlFile)).Substring( 264 | System.IO.Path.GetFileNameWithoutExtension(AggregationXmlFile).IndexOf(".") + 1), 265 | Extension = ".agg", 266 | FolderName = System.IO.Path.GetFileName(AggregationDir), 267 | FolderPath = AggregationDir, 268 | ObjectName = OLAPAggregationDesign.Name, 269 | Type = SSASObject.ObjectType.AggregationDesign, 270 | XMLFileName = System.IO.Path.GetFileName(AggregationXmlFile), 271 | XMLFilePath = AggregationXmlFile, 272 | XmlModifiedDate = AggregationXmlFile == "" ? dt : System.IO.File.GetLastWriteTime(AggregationXmlFile), 273 | FolderIncremetalID = System.IO.Path.GetFileNameWithoutExtension(AggregationDir).Substring( 274 | System.IO.Path.GetFileNameWithoutExtension(AggregationDir).IndexOf(".") + 1) 275 | 276 | }); 277 | 278 | 279 | } 280 | 281 | 282 | //Partitions 283 | foreach (Partition OLAPPartition in OLAPMeasureGroup.Partitions) 284 | { 285 | 286 | string PartitionDir = GroupPartitionDir.Where(x => x.StartsWith(MeasureGroupDir + "\\" + OLAPPartition.ID.ToString() + ".") && x.EndsWith(".prt")).DefaultIfEmpty("").First(); 287 | string PartitionXmlFile = GroupPartitionFiles.Where(x => x.StartsWith(MeasureGroupDir + "\\" + OLAPPartition.ID.ToString() + ".") && x.EndsWith(".prt.xml")).DefaultIfEmpty("").First(); 288 | 289 | idx++; 290 | 291 | result.Add(new SSASObject 292 | { 293 | ID = idx, 294 | ParentID = ObjectID, 295 | ObjectID = OLAPPartition.ID, 296 | FolderModifiedDate = PartitionDir == "" ? dt : System.IO.Directory.GetLastWriteTime(PartitionDir), 297 | XmlIncremetalID = System.IO.Path.GetFileNameWithoutExtension( 298 | System.IO.Path.GetFileNameWithoutExtension(PartitionXmlFile)).Substring( 299 | System.IO.Path.GetFileNameWithoutExtension(PartitionXmlFile).IndexOf(".") + 1), 300 | Extension = ".prt", 301 | FolderName = System.IO.Path.GetFileName(PartitionDir), 302 | FolderPath = PartitionDir, 303 | ObjectName = OLAPPartition.Name, 304 | Type = SSASObject.ObjectType.Partition, 305 | XMLFileName = System.IO.Path.GetFileName(PartitionXmlFile), 306 | XMLFilePath = PartitionXmlFile, 307 | XmlModifiedDate = PartitionXmlFile == "" ? dt : System.IO.File.GetLastWriteTime(PartitionXmlFile), 308 | FolderIncremetalID = System.IO.Path.GetFileNameWithoutExtension(PartitionDir).Substring( 309 | System.IO.Path.GetFileNameWithoutExtension(PartitionDir).IndexOf(".") + 1) 310 | 311 | }); 312 | 313 | } 314 | 315 | 316 | 317 | 318 | 319 | 320 | } 321 | 322 | 323 | } 324 | 325 | //Mining Structure 326 | foreach (MiningStructure OLAPMiningStructure in OLAPDatabase.MiningStructures) 327 | { 328 | 329 | idx++; 330 | 331 | string MiningStructureDir = DbObjectsDir.Where(x => x.StartsWith(CurrentDbDir + "\\" + OLAPMiningStructure.ID.ToString() + ".") && x.EndsWith(".dms")).DefaultIfEmpty("").First(); 332 | string MiningStructureXmlFile = DbObjectsFiles.Where(x => x.StartsWith(CurrentDbDir + "\\" + OLAPMiningStructure.ID.ToString() + ".") && x.EndsWith(".dms.xml")).DefaultIfEmpty("").First(); 333 | 334 | result.Add(new SSASObject 335 | { 336 | ID = idx, 337 | ParentID = DbID, 338 | ObjectID = OLAPMiningStructure.ID, 339 | FolderModifiedDate = MiningStructureDir == "" ? dt : System.IO.Directory.GetLastWriteTime(MiningStructureDir), 340 | XmlIncremetalID = System.IO.Path.GetFileNameWithoutExtension( 341 | System.IO.Path.GetFileNameWithoutExtension(MiningStructureXmlFile)).Substring( 342 | System.IO.Path.GetFileNameWithoutExtension(MiningStructureXmlFile).IndexOf(".") + 1), 343 | Extension = ".ds", 344 | FolderName = System.IO.Path.GetFileName(MiningStructureDir), 345 | FolderPath = MiningStructureDir, 346 | ObjectName = OLAPMiningStructure.Name, 347 | Type = SSASObject.ObjectType.MiningStructure, 348 | XMLFileName = System.IO.Path.GetFileName(MiningStructureXmlFile), 349 | XMLFilePath = MiningStructureXmlFile, 350 | XmlModifiedDate = MiningStructureXmlFile == "" ? dt : System.IO.File.GetLastWriteTime(MiningStructureXmlFile), 351 | FolderIncremetalID = System.IO.Path.GetFileNameWithoutExtension(MiningStructureDir).Substring( 352 | System.IO.Path.GetFileNameWithoutExtension(MiningStructureDir).IndexOf(".") + 1) 353 | 354 | }); 355 | } 356 | 357 | 358 | //Role 359 | foreach (Role OLAPRole in OLAPDatabase.Roles) 360 | { 361 | 362 | idx++; 363 | 364 | string RoleDir = DbObjectsDir.Where(x => x.StartsWith(CurrentDbDir + "\\" + OLAPRole.ID.ToString() + ".") && x.EndsWith(".dms")).DefaultIfEmpty("").First(); 365 | string RoleXmlFile = DbObjectsFiles.Where(x => x.StartsWith(CurrentDbDir + "\\" + OLAPRole.ID.ToString() + ".") && x.EndsWith(".dms.xml")).DefaultIfEmpty("").First(); 366 | 367 | result.Add(new SSASObject 368 | { 369 | ID = idx, 370 | ParentID = DbID, 371 | ObjectID = OLAPRole.ID, 372 | FolderModifiedDate = RoleDir == "" ? dt : System.IO.Directory.GetLastWriteTime(RoleDir), 373 | XmlIncremetalID = System.IO.Path.GetFileNameWithoutExtension( 374 | System.IO.Path.GetFileNameWithoutExtension(RoleXmlFile)).Substring( 375 | System.IO.Path.GetFileNameWithoutExtension(RoleXmlFile).IndexOf(".") + 1), 376 | Extension = ".ds", 377 | FolderName = System.IO.Path.GetFileName(RoleDir), 378 | FolderPath = RoleDir, 379 | ObjectName = OLAPRole.Name, 380 | Type = SSASObject.ObjectType.Role, 381 | XMLFileName = System.IO.Path.GetFileName(RoleXmlFile), 382 | XMLFilePath = RoleXmlFile, 383 | XmlModifiedDate = RoleXmlFile == "" ? dt : System.IO.File.GetLastWriteTime(RoleXmlFile), 384 | FolderIncremetalID = System.IO.Path.GetFileNameWithoutExtension(RoleDir).Substring( 385 | System.IO.Path.GetFileNameWithoutExtension(RoleDir).IndexOf(".") + 1) 386 | 387 | }); 388 | 389 | } 390 | 391 | } 392 | 393 | 394 | 395 | return result; 396 | } 397 | catch (Exception ex) 398 | { 399 | return null; 400 | } 401 | } 402 | 403 | } 404 | } 405 | -------------------------------------------------------------------------------- /MetaCube/Classes/SSASObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MetaCube 8 | { 9 | public class SSASObject 10 | { 11 | 12 | public enum ObjectType{ 13 | 14 | Cube = 0, 15 | MeasureGroup = 1, 16 | Dimension = 2, 17 | Partition = 3, 18 | AggregationDesign = 4, 19 | MiningStructure = 5, 20 | Role = 6, 21 | DataSource = 7, 22 | DataSourceView = 8, 23 | Database = 9, 24 | Server = 10, 25 | Kpi = 11, 26 | Action = 12 27 | 28 | } 29 | 30 | public int ID { get; set; } 31 | public int? ParentID { get; set; } 32 | public ObjectType Type { get; set; } 33 | public string ObjectID { get; set; } 34 | public string ObjectName { get; set; } 35 | public string Extension { get; set; } 36 | public string FolderPath { get; set; } 37 | public string FolderName { get; set; } 38 | public DateTime? FolderModifiedDate { get; set; } 39 | public string FolderIncremetalID { get; set; } 40 | public string XMLFilePath { get; set; } 41 | public string XMLFileName { get; set; } 42 | public DateTime? XmlModifiedDate { get; set; } 43 | public string XmlIncremetalID { get; set; } 44 | 45 | 46 | 47 | 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /MetaCube/Form1.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace MetaCube 2 | { 3 | partial class Form1 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.dataGridView1 = new System.Windows.Forms.DataGridView(); 32 | this.panel1 = new System.Windows.Forms.Panel(); 33 | this.button1 = new System.Windows.Forms.Button(); 34 | this.label1 = new System.Windows.Forms.Label(); 35 | this.ServerNametextbox = new System.Windows.Forms.TextBox(); 36 | ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); 37 | this.panel1.SuspendLayout(); 38 | this.SuspendLayout(); 39 | // 40 | // dataGridView1 41 | // 42 | this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 43 | this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill; 44 | this.dataGridView1.Location = new System.Drawing.Point(0, 45); 45 | this.dataGridView1.Name = "dataGridView1"; 46 | this.dataGridView1.Size = new System.Drawing.Size(1025, 445); 47 | this.dataGridView1.TabIndex = 0; 48 | // 49 | // panel1 50 | // 51 | this.panel1.Controls.Add(this.button1); 52 | this.panel1.Controls.Add(this.label1); 53 | this.panel1.Controls.Add(this.ServerNametextbox); 54 | this.panel1.Dock = System.Windows.Forms.DockStyle.Top; 55 | this.panel1.Location = new System.Drawing.Point(0, 0); 56 | this.panel1.Name = "panel1"; 57 | this.panel1.Size = new System.Drawing.Size(1025, 45); 58 | this.panel1.TabIndex = 1; 59 | // 60 | // button1 61 | // 62 | this.button1.Location = new System.Drawing.Point(418, 11); 63 | this.button1.Name = "button1"; 64 | this.button1.Size = new System.Drawing.Size(107, 23); 65 | this.button1.TabIndex = 2; 66 | this.button1.Text = "Retrieve objects"; 67 | this.button1.UseVisualStyleBackColor = true; 68 | this.button1.Click += new System.EventHandler(this.button1_Click); 69 | // 70 | // label1 71 | // 72 | this.label1.AutoSize = true; 73 | this.label1.Location = new System.Drawing.Point(12, 16); 74 | this.label1.Name = "label1"; 75 | this.label1.Size = new System.Drawing.Size(43, 13); 76 | this.label1.TabIndex = 1; 77 | this.label1.Text = "Server:"; 78 | // 79 | // ServerNametextbox 80 | // 81 | this.ServerNametextbox.Location = new System.Drawing.Point(61, 13); 82 | this.ServerNametextbox.Name = "ServerNametextbox"; 83 | this.ServerNametextbox.Size = new System.Drawing.Size(351, 20); 84 | this.ServerNametextbox.TabIndex = 0; 85 | // 86 | // Form1 87 | // 88 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 89 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 90 | this.ClientSize = new System.Drawing.Size(1025, 490); 91 | this.Controls.Add(this.dataGridView1); 92 | this.Controls.Add(this.panel1); 93 | this.Name = "Form1"; 94 | this.Text = "Form1"; 95 | this.Load += new System.EventHandler(this.Form1_Load); 96 | ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); 97 | this.panel1.ResumeLayout(false); 98 | this.panel1.PerformLayout(); 99 | this.ResumeLayout(false); 100 | 101 | } 102 | 103 | #endregion 104 | 105 | private System.Windows.Forms.DataGridView dataGridView1; 106 | private System.Windows.Forms.Panel panel1; 107 | private System.Windows.Forms.Button button1; 108 | private System.Windows.Forms.Label label1; 109 | private System.Windows.Forms.TextBox ServerNametextbox; 110 | } 111 | } 112 | 113 | -------------------------------------------------------------------------------- /MetaCube/Form1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace MetaCube 12 | { 13 | public partial class Form1 : Form 14 | { 15 | public Form1() 16 | { 17 | InitializeComponent(); 18 | } 19 | 20 | private void Form1_Load(object sender, EventArgs e) 21 | { 22 | 23 | } 24 | 25 | private void button1_Click(object sender, EventArgs e) 26 | { 27 | dataGridView1.DataSource = MetaCube.SSASAMO.ReadMeta(ServerNametextbox.Text); 28 | dataGridView1.AutoResizeColumns(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /MetaCube/Form1.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /MetaCube/MetaCube.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {CA89E548-2038-4F5B-8E28-29EC839D6339} 8 | WinExe 9 | Properties 10 | MetaCube 11 | MetaCube 12 | v4.5 13 | 512 14 | publish\ 15 | true 16 | Disk 17 | false 18 | Foreground 19 | 7 20 | Days 21 | false 22 | false 23 | true 24 | 0 25 | 1.0.0.%2a 26 | false 27 | false 28 | true 29 | 30 | 31 | AnyCPU 32 | true 33 | full 34 | false 35 | bin\Debug\ 36 | DEBUG;TRACE 37 | prompt 38 | 4 39 | 40 | 41 | AnyCPU 42 | pdbonly 43 | true 44 | bin\Release\ 45 | TRACE 46 | prompt 47 | 4 48 | 49 | 50 | 51 | True 52 | 53 | 54 | 55 | 56 | 57 | 58 | True 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | Form 69 | 70 | 71 | Form1.cs 72 | 73 | 74 | 75 | 76 | 77 | 78 | Form1.cs 79 | 80 | 81 | ResXFileCodeGenerator 82 | Resources.Designer.cs 83 | Designer 84 | 85 | 86 | True 87 | Resources.resx 88 | 89 | 90 | SettingsSingleFileGenerator 91 | Settings.Designer.cs 92 | 93 | 94 | True 95 | Settings.settings 96 | True 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | False 105 | Microsoft .NET Framework 4.5 %28x86 and x64%29 106 | true 107 | 108 | 109 | False 110 | .NET Framework 3.5 SP1 111 | false 112 | 113 | 114 | 115 | 122 | -------------------------------------------------------------------------------- /MetaCube/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace MetaCube 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// The main entry point for the application. 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | Application.EnableVisualStyles(); 18 | Application.SetCompatibleTextRenderingDefault(false); 19 | Application.Run(new Form1()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /MetaCube/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MetaCube")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("MetaCube")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("e82457aa-4ee7-4f0f-ba61-f2eca2ea2092")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MetaCube/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18408 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MetaCube.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MetaCube.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /MetaCube/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /MetaCube/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18408 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MetaCube.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /MetaCube/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MetaCube 2 | 3 | MetaCube is a tool that can be used to read the SQL Server Analysis Server Objects using AMO assemblies and map each object to the related directory and configuration files located in the server data directory (DataDir property). 4 | 5 | You can use the Classes within your own solution or you can use the application as a tool. 6 | 7 | --------------------------------------- 8 | 9 | # SSAS Data directory contents hierarchy 10 | 11 | After building many multidimensional Cube using SSAS, i can assume that the following tree is the Data directory hierarchy: 12 | 13 | |- Data Directory 14 | |- Database (.db) 15 | |- Dimension (.dim) 16 | |- Role (.role) 17 | |- Mining Structure (.dms) 18 | |- Data Source (.ds) 19 | |- Data Source View (.dsv) 20 | |- Multidimensional Cube (.cub) 21 | |- Measure Group (.det) 22 | |- Partition (.prt) 23 | |- AggregationDesign (.agg) 24 | 25 | 26 | Each object from the tree above can be stored in form of a directory or/and an XML file. 27 | 28 | The Actions and Kpis information are stored within the Cube XML configuration file. 29 | 30 | *Example:* 31 | 32 | - Object: Cube 33 | - Directory: `\\.cub\` 34 | - XML file: `\\.cub.xml` 35 | 36 | 37 | # Link SSAS AMO objects to data directory files 38 | 39 | ## Reading data using AMO 40 | 41 | To read SSAS object from deployed Analysis Cube, i improved the code of the following project to add more objects and to link them with the relevant directories/files. 42 | 43 | - [SSASAMODB](https://github.com/msornakumar/SSASAMODB) 44 | 45 | 46 | ## Updated method 47 | 48 | To map every AMO object to the relevant directory/XML file we have to loop over objects starting from top level (database) and retrieve the files/directories found in each level and map it using the .ID property and the extensions (as mentioned in the tree above) 49 | 50 | The following code is written in C# and it is an updated version of the method published in the link above: 51 | 52 | **Note that the method only works on local servers or you must have a Mapped network drive with the same letter of the Original drive that contains the data directory. In addition you must have the permission to access the Analysis Server objects** 53 | 54 | ### Reading meta data 55 | 56 | You can simply read the data by passing the server name to the `ReadMeta()` function: 57 | 58 | ```cs 59 | dataGridView1.DataSource = MetaCube.SSASAMO.ReadMeta(@"Machine\Instance"); 60 | ``` 61 | 62 | ### SSASObject Class 63 | 64 | The `ReadMeta()` function returns a `List`: 65 | 66 | 67 | ```cs 68 | public class SSASObject 69 | { 70 | 71 | public enum ObjectType{ 72 | 73 | Cube = 0, 74 | MeasureGroup = 1, 75 | Dimension = 2, 76 | Partition = 3, 77 | AggregationDesign = 4, 78 | MiningStructure = 5, 79 | Role = 6, 80 | DataSource = 7, 81 | DataSourceView = 8, 82 | Database = 9, 83 | Server = 10, 84 | Kpi = 11, 85 | Action = 12 86 | 87 | } 88 | 89 | public int ID { get; set; } //incremental ID 90 | public int? ParentID { get; set; } // Parent incremental ID 91 | public ObjectType Type { get; set; } // The Object type 92 | public string ObjectID { get; set; } // Object ID defined in SSAS 93 | public string ObjectName { get; set; } // Object Name defined in SSAS 94 | public string Extension { get; set; } // The Object extension 95 | public string FolderPath { get; set; } // The Object related directory 96 | public string FolderName { get; set; } // The directory name 97 | public DateTime? FolderModifiedDate { get; set; } // The directory last modified date 98 | public string FolderIncremetalID { get; set; } // The Incremental Number mentioned in the directory name 99 | public string XMLFilePath { get; set; } // The Object related XML file 100 | public string XMLFileName { get; set; } // The XML file name 101 | public DateTime? XmlModifiedDate { get; set; } // The XML file last modified date 102 | public string XmlIncremetalID { get; set; } // The incremental number mentioned in the XML file name 103 | 104 | 105 | } 106 | ``` 107 | 108 | --------------------------------------------------------------------------------