January 19, 2021
Hot Topics:

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

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


Executing the parsing and generating data all starts behind the WPF Application "Run" button. The Run button code appears below.

  GridView view;
  DBMediator med = new DBMediator();
  GridViewLayoutBuilder viewBuild = new GridViewLayoutBuilder();
  DataSet ds = null;
  List configList = null;
  MParserBuilder parser = new MParserBuilder();
  MGraphGenerator graphGen = new MGraphGenerator();
  MGraphIterator iterator = null;
  MGraphTSQLQueryVisitor visitor = new MGraphTSQLQueryVisitor();
  List visitors = new List();
  graphGen.Run(this._inputText.Text, parser.Parser);
  visitor.Graph = graphGen.Builder;
  iterator = new MGraphIterator(graphGen.Builder, graphGen.GraphRoot, visitors);
  this.SQLCode.Text = visitor.TSQL;
  //Now view the data
  view = (GridView)this.SQLData.View;
  ds = med.GetDataSet(this.SQLCode.Text);
  configList = (new GridViewColumnConfigBuilder(ds.Tables[0].Columns)).GetColumnNames();
  viewBuild.View = view;
  this.SQLData.DataContext = ds;
  this.SQLData.ItemsSource = ds.Tables[0].Rows;

Classes declared at the top of the code have the following responsibilities.

  • GridView handles rendering the DataSet data.
  • DBMediator accepts a SQL query and returns a DataSet.
  • GridViewLayoutBuilder changes the GridView to match the DataSet
  • MParserBuilder builds the Oslo DynamicParser from the M code
  • MGraphGenerator uses the DynamicParser to build a GraphBuilder object.
  • MGraphIterator navigates the GraphBuilder object, invoking a IGraphVisitor object at each node.
  • MGraphTSQLQueryVisitor is the implementation of IGraphVisitor and handles SELECT statement construction.

I'll highlight the critical parts of each class beginning with the Iterator.

Navigating a Graph -- Iterator

In my prior article I demonstrated how a developer can incorporate the M code. You can view that article here http://www.codeguru.com/columns/experts/article.php/ c16043/ . In the prior article I navigated an Oslo Data structure called GraphBuilder.

GraphBuilder is generated by the Oslo classes from the text input and the MGrammar loaded in the application. GraphBuilder is a hiearchal data structure somewhat matching the shape of the MGraph-like data generated in the Tree view of Intellipad. A sample from Intellipad appears below.

Click here for larger image

Figure 3: Intellipad MGraph

To consume the data I chose to construct code following two well known software patterns, the Iterator pattern embodied in the MGraphIterator class and the Visitor pattern embodied in the IMGraphIterator interface. For a complete description of the patterns refer to the sources at the end of the article.

Also, the Iterator I built does not implement IEnumerable, so you can't utilize the C# foreeach statement with the Iterator. The Iterator name refers to the pattern not the implementation.

MGraphIterator and a class implementing IMGraphIterator work like this. As viewed above, GraphBuilder is a tree-like data structure. MGraphIterator recursively traverses the nodes on the GraphBuilder invoking the Accept function on a list of IMGraphIterator based classes. A portion of the code appears below.

          public void Traverse ()
              WalkTheNodes(_graph, _root,_visitors);
          private void WalkTheNodes(System.Dataflow.GraphBuilder graph, object nodeOn, List<IMGRAPHVISITOR> visitors)
              bool isNode = false;
              foreach (object enumNext in graph.GetSuccessors(nodeOn))
                  isNode = graph.IsNode(enumNext);
                  if ((isNode)) //Skip the non-nodes
                      foreach (IMGraphVisitor visitor in visitors)
                      WalkTheNodes(graph, enumNext, visitors);//Recurse to next node   

I envisioned making the Iterator/Visitor interaction a reusable pattern. Different M languages could produce different GraphBuilders, but I thought that every GraphBuilder would be traversed in a similar manner. So, I decided to defer GraphBuilder consumption to an implementation of an interface following the Visitor pattern.

Now I'll show how I implemented a visitor for a GraphBuilder created from my "Simple SQL" DSL.

Page 3 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