Click here to Skip to main content
15,884,298 members
Articles / Database Development / SQL Server

Introduction to SQL Server Domain Modeling with the "M" Language

Rate me:
Please Sign up or sign in to vote.
4.75/5 (6 votes)
30 Mar 2011CPOL15 min read 35K   216   13  
SQL Server domain modeling with Oslo CTP and the "M" language.
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//----------------------------------------------------------------

namespace PersonExample
{
    using System;
    using System.Collections.Generic;
    using System.Dataflow;
    using System.IO;
    using MGraphXamlReader;
    using Microsoft.M;

    class Example
    {
        static string testGrammar = @"
module Example {
    language Family {
        interleave Whitespace = ' '|'\n'|'\r'|'\t';
        token Name = ('a'..'z'|'A'..'Z')+;
        
        syntax Persons
            = p:Person 
                => [p]
            | list:Persons "","" p:Person 
                => [valuesof(list), p];

        syntax Children
            = ""{"" p:Persons ""}"" "";""
                => p;
        
        syntax Person 
            = first:Name last:Name
                => Person {
                    First => first ,
                    Last => last 
                }
            | first:Name last:Name c:Children
                => Person { 
                    First => first, 
                    Last => last, 
                    Children => c 
                };
                
        syntax Main 
            = p:Person* 
                => p;
    }
}
";

        static string testInput = @"
Bob Williams
{ 
    Joanie Williams,
    Cathy Williams,
    Bob Williams
    {
        Josh Williams,
        Jennie Williams,
        Julie Williams
    };
};
";

        static Parser LoadExampleGrammar()
        {
            using (var options = new CompilerOptions())
            {
                var sourceItems = new SourceItem[] {
                    new TextItem()
                    {
                        Name = "Test Grammar",
                        ContentType = TextItemType.MGrammar,
                        Reader = new StringReader(testGrammar)
                    }
                };

                options.AddSourceItems(sourceItems);

                CompilationResults results = Compiler.Compile(TargetTypes.Parser, options);
                if (results.HasErrors)
                {
                    throw new Exception("Failure compiling Test Grammar");
                }
                foreach (var x in results.ParserFactories)
                {
                    return x.Value.Create();
                }
            }
            return null;
        }

        public static void RunExample()
        {
            Parser parser = LoadExampleGrammar();

            var xamlMap = new Dictionary<Identifier, Type> { { "Person", typeof(Person) } };

            var people = parser.Parse<List<object>>(testInput, xamlMap);

            Console.WriteLine();

            foreach (Person p in people)
            {
                p.Print(0);
            }
        }

        public static void Main()
        {
            RunExample();
            Console.WriteLine("Press ENTER to exit application");
            Console.ReadLine();
        }
    }

    // Generic just to test the point...
    public class Person
    {
        List<Person> children = new List<Person>();

        public string First { get; set; }
        public string Last { get; set; }
        public ICollection<Person> Children { get { return children; } }

        public void Print(int depth)
        {
            Console.WriteLine(
                new String(' ', depth) +
                "I am a person named: " +
                First.ToString() +
                " " +
                Last.ToString() +
                ", and I have " +
                Children.Count +
                " Children:");

            foreach (var child in Children)
            {
                child.Print(depth + 1);
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United Kingdom United Kingdom
Frank Kerrigan

Currently developing Insurance systems with SQL Server, ASP.NET, C#, ADO for a company in Glasgow Scotland. Very keen on OOP and NUNIT testing. Been in IT forever (20 years) in mix of development and supporting applications / servers. Worked for companies big and small and enjoyed both.

Developed in (newest first) : C#, Progress 4GL, ASP.NET, SQL TSQL, HTML, VB.NET, ASP, VB, VBscript, JavaScript, Oracle PSQL, perl, Access v1-2000, sybase/informi, Pic Controllers, 6502 (ask your dad).

Msc .Net Development Evenings www.gcu.ac.uk
MCAD Passed
MCP C# ASP.NET Web Applications
MCP SQL Server 2000
HND Computing
OND / HNC Electrical Engineering,

Comments and Discussions