January 23, 2021
Hot Topics:

Developing a TSQL Domain Specific Language with "M" and the Microsoft Oslo SDK

  • By Jeffrey Juday
  • Send Email »
  • More Articles »

The Visitor

MGraphTSQLQueryVisitor implements the IGraphVisitor interface. Main parts of the Accept function appear below.
          public void Accept(object node)
              List<OBJECT> vals;
              string seqLabel = "";
              object seqLabelObj = null;
              string tempVal = "";
              string originalVal = "";
              seqLabelObj = _graph.GetSequenceLabel(node);
              if (seqLabelObj != null) //Sometimes label returns null value
                  seqLabel = seqLabelObj.ToString();
                  if (seqLabel == "TableReg")
                  if (seqLabel == "TableAlias") 
                  if (seqLabel == "INTERSECT") 
                  if (seqLabel == "Data")
                      vals = GetSuccessorsTo(node);
                      foreach (object obj in vals)
                          _selectFieldSection.Add( GetFirstSuccessorAtDepth(obj, 5));

As you can see above MGraphTSQLQueryVisitor executes different code depending on the visited Node. When a node contains a root with the first word in one of the projections, Accept retrieves the information in levels below the Node being visited.

MGraphTSQLQueryVisitor leverages a class called TSQLTableNameSchemaResolver. TSQLTableNameSchemaResolver is pseudo database-aware. Business users are probably not aware of Schema information. So TSQLTableNameSchemaResolver qualifies the utilized tables with the correct schema information. I envisioned this class querying system tables in the database to match tables entered in the DSL code.

Some internal collections store what is retrieved from GraphBuilder so that the SELECT statement can be assembled and executed. WPF application code handles data display.

Displaying Data

The sample is a WPF Application. So the GridView rendering classes I'll review shortly use the WPF controls. A complete review of WPF GridView controls is beyond the scope of this article. Sources at the end of the article contain more WPF information.

DBAccess executes the generated TSQL, creating a DataSet from standard ADO.NET code.

Using the View attached to the SQLData Control on Window1, GridViewLayoutBuilder builds a GridView based on a ColumnConfig collection assembled by the GridViewColumnConfigBuilder class from column information in the DataSet. Code assembling the Grid columns appears below.

          public void SetColumns(List<COLUMNCONFIG> columnConfig)
              GridViewColumn col = null;
              foreach (ColumnConfig config in columnConfig)
                  col = new GridViewColumn();
                  col.Width = 50;
                  col.DisplayMemberBinding = new Binding(config.BindingPath);
                  col.Header = config.DisplayName;

GridViewColumnConfigBuilder formats the Binding path to point to the correct data inside the DataSet. WPF leverages the BindingPath to find the column data inside the DataSet.


In a prior article I showed how to incorporate a DSL written in M into a .NET application. This article tackled a more advanced task. In particular, it implemented a more advanced DSL called "Simple SQL" and demonstrated more sophisticated patterns for consuming data structures generated by the DSL and the Oslo SDK.


Oslo SDK documentation and Samples shipping with Oslo SDK CTP January 2009
MSDN - "Textual Domain Specific Languages for Developers - Part 2"
Software Patterns - Iterator
Software Patterns - Visitor
WPF sources - GridView Overview

Page 4 of 4

This article was originally published on May 5, 2009

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date