January 29, 2020
Hot Topics:

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

  • May 5, 2009
  • 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

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