/// <summary> /// Extracts measure names from database object. /// </summary> /// <param name="tableName">Specifies a table that will limit measure names to that specific one.</param> /// <returns>Returns list of measure names specific to a table or all of them if tableName is empty.</returns> /// <exception cref="System.InvalidOperationException">Thrown when database object is null.</exception> public IEnumerable <string> GetMeasureNames(string tableName) { if (null == this._database) { throw new InvalidOperationException("Current database is NULL. GetMeasureNames function cannot be called when database object is NULL"); } var measureNames = new List <string>(); if (this._database.Cubes.Count > 0) { var cube = this._database.Cubes[0]; if (cube.MdxScripts.Count > 0) { var mdxScrit = cube.MdxScripts[0]; foreach (Command mdxCommand in mdxScrit.Commands) { if (!string.IsNullOrEmpty(mdxCommand.Text)) { var measures = MeasuresContainer.ParseDaxScript(mdxCommand.Text).Measures; if (string.IsNullOrEmpty(tableName)) { measureNames.AddRange(measures.Select(i => i.TableName + i.Name)); } else { measureNames.AddRange(measures.Where(i => string.Equals(i.TableName, tableName, StringComparison.CurrentCultureIgnoreCase)).Select(i => i.TableName + i.Name)); } } } } } return(measureNames); }
internal string GetMeasuresText() { if (this._database == null) { if (_isConnecting) { return("-- Reading metadata from the database. Please retry operation later."); } return("-- Not connected to the database."); } var sb = new StringBuilder(); var restrictions = new AdomdRestrictionCollection(); restrictions.Add("DatabaseID", _database.ID); var dataSet = _adomdConn.GetSchemaDataSet("DISCOVER_XML_METADATA", restrictions); Debug.Assert(dataSet.Tables.Count == 1); var table = dataSet.Tables[0]; Debug.Assert(table.Columns.Count == 1); Debug.Assert(table.Rows.Count == 1); var script = table.Rows[0][0] as string; Debug.Assert(!string.IsNullOrEmpty(script)); var mc = MeasuresContainer.ParseText(script); sb.Append(mc.GetDaxText()); return(sb.ToString()); }
void BackgroundWorker_SaveMeasuresAndCalcColumns(object sender, DoWorkEventArgs e) { var cmdProducer = new ServerCommandProducer(_database.Name, _database.CompatibilityLevel, _database.Cubes[0].Name); try { var bw = sender as BackgroundWorker; bw.DoWork -= new DoWorkEventHandler(BackgroundWorker_SaveMeasuresAndCalcColumns); LogLine("Begin saving measures."); string viewText = e.Argument as string; var mc = MeasuresContainer.ParseDaxScript(viewText); LogLine("Begin transaction."); using (var cmd = new AdomdCommand("@CommandText", _adomdConn)) { cmd.Parameters.Add(new AdomdParameter("CommandText", cmdProducer.ProduceBeginTransaction())); cmd.ExecuteNonQuery(); } LogLine("Alter MDX script."); using (var cmd = new AdomdCommand("@CommandText", _adomdConn)) { cmd.Parameters.Add(new AdomdParameter("CommandText", cmdProducer.ProduceAlterMdxScript(mc.Measures))); cmd.ExecuteNonQuery(); } LogLine("Run ProcessRecalc."); using (var cmd = new AdomdCommand("@CommandText", _adomdConn)) { cmd.Parameters.Add(new AdomdParameter("CommandText", cmdProducer.ProduceProcessRecalc())); cmd.ExecuteNonQuery(); } LogLine("Commit transaction."); using (var cmd = new AdomdCommand("@CommandText", _adomdConn)) { cmd.Parameters.Add(new AdomdParameter("CommandText", cmdProducer.ProduceCommitTransaction())); cmd.ExecuteNonQuery(); } LogLine("End saving measures."); } catch (Exception ex) { using (var cmd = new AdomdCommand("@CommandText", _adomdConn)) { cmd.Parameters.Add(new AdomdParameter("CommandText", cmdProducer.ProduceRollbackTransaction())); cmd.ExecuteNonQuery(); } LogError("Error while saving measures. " + ex.ToString()); } }
/// <summary> /// Gets Measures section of BIM file /// </summary> internal static string GetMeasuresFromBimFile(string bimFilePath) { try { if (!File.Exists(bimFilePath)) { throw new FileNotFoundException(string.Format("Model file {0} doesn't exist.", bimFilePath)); } string bimScript = File.ReadAllText(bimFilePath); var mc = MeasuresContainer.ParseText(bimScript); return(mc.GetDaxText()); } catch (Exception e) { throw new DaxException(string.Format("Error while reading measures from file '{0}'", bimFilePath), e); } }
/// <summary> /// Saves DAX file to Measures section of BIM file /// </summary> internal static void SaveMeasuresToBimFile(string daxFilePath) { string daxFileContent = File.ReadAllText(daxFilePath); string customScript = null; //TL: If DAX file includes custom MDX script, remove it to avoid interference with parser if (daxFileContent.Contains(BeginCustomScript)) { // read custom script customScript = daxFileContent.Substring(daxFileContent.IndexOf(BeginCustomScript, StringComparison.InvariantCultureIgnoreCase), daxFileContent.IndexOf(EndCustomScript, EndCustomScript.Length, StringComparison.InvariantCultureIgnoreCase) + EndCustomScript.Length); // remove custom script daxFileContent = daxFileContent.Replace(customScript, String.Empty); } var mc = MeasuresContainer.ParseDaxScript(daxFileContent); string bimFilePath = ConvertDaxPathToBimPath(daxFilePath); if (!File.Exists(bimFilePath)) { throw new FileNotFoundException(string.Format("Model file {0} doesn't exist", bimFilePath)); } if (new FileInfo(bimFilePath).IsReadOnly) { throw new InvalidOperationException(string.Format("Model file {0} is read only", bimFilePath)); } // TL -- injecting custom MDX script verbatum to the bim file if (!string.IsNullOrEmpty(customScript)) { // insert customScript as first measure so it gets serialized first DaxMeasure m = new DaxMeasure(); m.Name = "CustomMDXScript"; m.FullText = customScript; mc.Measures.Insert(0, m); } string bimScript = System.IO.File.ReadAllText(bimFilePath); var updatedScript = mc.UpdateMeasures(bimScript); File.WriteAllText(bimFilePath, updatedScript); }
public string ProduceAlterScriptElement(MeasuresContainer container) { var stream = new MemoryStream(); var writer = new XmlTextWriter(stream, Encoding.UTF8); var obj = container.ToMdxScript(_dbCompatibilityLevel); Utils.Serialize(writer, obj, true); stream.Position = 0; var text = new StreamReader(stream).ReadToEnd(); //Delete default nodes var document = XDocument.Parse(text); document.Descendants(MeasuresContainer.NS + "CreatedTimestamp").Remove(); document.Descendants(MeasuresContainer.NS + "LastSchemaUpdate").Remove(); document.Descendants(MeasuresContainer.NS + "Value").Where(i => i.IsEmpty).Remove(); document.Element(MeasuresContainer.NS + "MdxScript").RemoveAttributes(); return(document.ToString(SaveOptions.OmitDuplicateNamespaces)); }
/// <summary> /// Constructs declarations cache based on database object /// </summary> private void ConstructSchemaBasedDeclarations() { LogLine("Begin constructing schema based declarations."); List <Declaration> tableDeclarations = new List <Declaration>(); List <Declaration> measureDeclarations = new List <Declaration>(); Dictionary <string, List <Declaration> > tableMembersDeclarations = new Dictionary <string, List <Declaration> >(); List <string> tableList = new List <string>(); List <string> columnList = new List <string>(); List <string> measureList = new List <string>(); if (null == this._database) { ClearDeclarationsCache(); LogLine("ERROR: Database is not defined."); return; } foreach (Microsoft.AnalysisServices.Dimension dim in _database.Dimensions) { // Set table declarations tableDeclarations.Add(new Babel.Declaration(dim.Description, dim.Name, Babel.LanguageService.TABLE_GLYPH_INDEX, dim.Name)); tableList.AddRange(GenerateValidTableNames(dim.Name)); // Obtain column declarations for current table List <Declaration> columnDeclarationsCurrentTable = new List <Declaration>(); foreach (DimensionAttribute dimAttr in dim.Attributes) { // Skip RowNumber columns if (_rowNumberColumnNames.Any(i => { return(string.Equals(i, dimAttr.Name, StringComparison.CurrentCultureIgnoreCase)); })) { continue; } var columnShortName = "[" + dimAttr.Name + "]"; if (dimAttr.Source is ExpressionBinding) { // use calc column glyph columnDeclarationsCurrentTable.Add(new Babel.Declaration(dimAttr.Description, dimAttr.Name, Babel.LanguageService.CALC_COLUMN_GLYPH_INDEX, columnShortName)); } else { // use base column glyph columnDeclarationsCurrentTable.Add(new Babel.Declaration(dimAttr.Description, dimAttr.Name, Babel.LanguageService.BASE_COLUMN_GLYPH_INDEX, columnShortName)); } GenerateValidTableNames(dim.Name).ForEach(i => columnList.Add(string.Format("{0}{1}", i, columnShortName))); } tableMembersDeclarations.Add(dim.Name, columnDeclarationsCurrentTable); } // Obtain measure declarations and distribute them in table member declarations if (this._database.Cubes.Count > 0) { var cube = this._database.Cubes[0]; if (cube.MdxScripts.Count > 0) { var mdxScript = cube.MdxScripts[0]; foreach (Command mdxCommand in mdxScript.Commands) { if (!string.IsNullOrEmpty(mdxCommand.Text)) { var measures = MeasuresContainer.ParseDaxScript(mdxCommand.Text).Measures; foreach (var measure in measures) { // Add measure declaration to the global collection var measureShortName = "[" + measure.Name + "]"; measureDeclarations.Add(new Babel.Declaration(measure.Expression, measure.Name, Babel.LanguageService.MEASURE_GLYPH_INDEX, measureShortName)); GenerateValidTableNames(measure.TableName).ForEach(i => measureList.Add(string.Format("{0}{1}", i, measureShortName))); // Add the measure declaration to the table member declaration list if (tableMembersDeclarations.ContainsKey(measure.TableName)) { tableMembersDeclarations[measure.TableName].Add(new Babel.Declaration(measure.Expression, measure.Name, Babel.LanguageService.MEASURE_GLYPH_INDEX, measureShortName)); } } } } } } // Create HTML table string htmlSchemaTemplate; using (var textStreamReader = new StreamReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("DaxEditor.Resources.ScemaTemplate.htm"))) { htmlSchemaTemplate = textStreamReader.ReadToEnd(); } var htmlSchemaBuilder = new StringBuilder(); foreach (var td in tableMembersDeclarations) { htmlSchemaBuilder.AppendFormat(BeginTableTemplate, HtmlEncode(td.Key)); foreach (var decl in td.Value) { if (_rowNumberColumnNames.Any(i => { return(string.Equals(i, decl.Name, StringComparison.CurrentCultureIgnoreCase)); })) { continue; } switch (decl.Glyph) { case Babel.LanguageService.BASE_COLUMN_GLYPH_INDEX: htmlSchemaBuilder.AppendFormat(RowTemplate, "column", HtmlEncode(decl.Name)); break; case Babel.LanguageService.CALC_COLUMN_GLYPH_INDEX: htmlSchemaBuilder.AppendFormat(RowTemplate, "calcolumn", HtmlEncode(decl.Name)); break; case Babel.LanguageService.MEASURE_GLYPH_INDEX: htmlSchemaBuilder.AppendFormat(RowTemplate, "measure", HtmlEncode(decl.Name)); break; } } htmlSchemaBuilder.Append(EndTableTemplate); } htmlSchemaTemplate = htmlSchemaTemplate.Replace(TablesPlaceholder, htmlSchemaBuilder.ToString()); // Commit the newly created declarations into the cache lock (this) { this._tableDeclarations = tableDeclarations; this._measureDeclarations = measureDeclarations; this._tableMembersDeclarations = tableMembersDeclarations; this._htmlSchema = htmlSchemaTemplate; _completionDataSnapshot = new CompletionDataSnapshot(_completionDataSnapshot, tableList, columnList, measureList); } LogLine("End constructing schema based declarations."); }