Use Case: Getting compiler feedback on your database design

Abstract

Database build scripts have, for a long time been glorified strings that cannot be validated until executed on a database server. Of course, there is no way to totally validate any code until it has been loaded into a realistic environment and thoroughly tested. However, a lot of simple things can be caught at compile time if you have a compiler. DataClass does exactly that, giving you quick feedback when your database construction steps reference symbols that have not been specified.

Learning Objectives

Body

DataClass is a first class language that lets you define a class of databases rather than worry about individual instances. It compiles everything you tell it - version info, construction steps, etc. - into a .NET assembly and/or a java JAR file. The resulting class of databases then knows how to, say, build a new database or upgrade one that was previously built.

Part of defining a class of databases is defining the design of its instances. This is accomplished using the design keyword as in the following example.

You can click on keywords and concepts in blue.
handdesign
{
  public table SomeTable
  {
    public column SomeColumn
      with DataType=type(nvarchar(20));
    public column SomeOtherColumn
      with DataType=type(int, not null);
  }
}

Let's look at how we can use a symbol:

You can click on keywords and concepts in blue.
handdatabase CrackerDB
{
  /*
  We have to define a mapping between data 
  and client types
  */
  types int as integer, nvarchar as string;
  
  version 1.0 : initialized
  {
    /*
    Design is intentionally specified
    separately from construction
    */
    design
    {
      protected table Crackers
      {
        public column ID with
          DataType = type(int);
          
        public column Description with
          DataType = type(nvarchar(255));
          
        public column Crispness with
          DataType = type(int);
      }
    }
    
    construction
    {
      step sql
      {
CREATE TABLE $[Crackers](
  $[Crackers.ID] $[Crackers.ID.DataType],
  $[Crackers.Description] $[Crackers.Description.DataType],
  $[Crackers.Crispness] $[Crackers.Crispness.DataType]);
      }
    }
  }
}

Now, if we hadn't typed everything perfectly, we would get a compiler error. Imagine that we introduce a typo into the CREATE TABLE statement such that "Crispness" was spelled "Crispnes," as in the following code.

You can click on keywords and concepts in blue.
CREATE TABLE hand$[Crackers](
  $[Crackers.ID] $[Crackers.ID.DataType],
  $[Crackers.Description] $[Crackers.Description.DataType],
  $[Crackers.Crispnes] $[Crackers.Crispness.DataType]);

The next time we compile our class of database - which should be pretty shortly after we made that mistake because we were introducing a change - we will get the following error:

C:\HexagonSoftwareProducts\DataClass\CouplingExamples\CrackerDB.dbc(33,14): error : ↵
  Could not bind to symbol 'Crackers.Crispnes'.
        

So, immediately, we start getting a little bit of feedback from DataClass but that's not really the point, that's just the hook to reel you in. Future versions can also benefit from this design information, too. For instance, if a future version requires you to migrate from using one-to-ten crispness ratings over to one-to-one-hundred, you would probably want to write a script that multiplies all of the existing ratings by ten. That new SQL statement is able to benefit from all of the existing design documentation you have generated to get your database to the state it is presently in:

You can click on keywords and concepts in blue.
UPDATE hand$[Crackers] SET $[Crackers.Crispness] = $[Crackers.Crispness] * 10;

Were that statement typed incorrectly, say the table name was typed as $[Cracker] instead of $[Crackers], the dbcc compiler would generate an error indicating what the problem was and where it lived.

A side-effect of having a compiler that generates errors is that you are protected from certain categories of invalid binary being generated. There is no way for the above code sample to be useful, so DataClass prevents it from ever being turned into a binary who's behaviors might ultimately be inflicted on a live database.

Related Use Cases

Related Concepts

Related Keywords

Other Actions

documentation | all examples | use cases | concepts | keywords