Using Continuous Database

Learn practical information how to apply make SuperOffice database changes.
Ratings

With an understanding of what Continuous Database is, it’s now time to dive into the details and learn how to put that knowledge to use. This article will teach how to use your DictionarySteps to make database changes.

How It Works

The previous continuous database article described the motivation for adopting this methodology, as well as what DictionarySteps are and how to create them.

In the example below, MovieStep1 implements the Structure method where two new tables are defined. Using the create method to begin the process, a fluent interface makes it easy to add table properties and fields to the table all in one statement.

Each method in the Structure method will be translated into a command. CreateTable, for instance, is transformed into a create table command, and each of the Add methods is transformed into an add field command.

Individually, each command is known as a BuilderCommand. Even the Dictionary attribute and any defined indexes are transformed into respective commands.

There are several types of command builders, where each builder knows how to access and build a list of commands from each unique resource.

For example, a CommandFromStepBuilder knows how to build a command list from a DictionaryStep, such as in the MovieStep1 class. Another command builder called CommandFromEjExtraBuilder, knows how to build a command list from all SuperOffice Customer Service Extra_Table and Extra_Field tables.

Applicators then use the command lists to perform various tasks. For example, the DatabaseModelApplicator is responsible for both command validation and transforming the command list into database model types – such as TableModel, FieldModel, IndexMode, RelationModel, etc.

Once the in-memory database model has been checked and validated, the physical applicators perform all physical changes to the database.

Continuous Database Requirements

In the retired DictionarySDK, which is obsolete with SuperOffice 8.1, third-parties had to install a Windows Client to have all of the required components installed to use it.

With Continuous Database, all functionality is contained in two assemblies, SuperOffice.CD.DSL.dll and SuperOffice.CD.DSL.Implementation.dll.

Soon, there will be a NuGet package called SuperOffice.ContinuousDatabase to obtain these assemblies. Until then, just get them from the SuperOffice.NetServer.Core package, or any installation of SuperOffice (Win, Web, or Web Services).

Typical Continuous Database Workflow

 

As a third-party developer, the typical workflow begins when you have an integration idea that needs to either extend or create a table in the SuperOffice database. Detailed in the Continuous Database article, this begins with the creation of a new Dictionary Step.

Make sure that the assembly created is done so without any unnecessary assembly references. The only external references your DictionaryStep assembly should have is to the assemblies included in the SuperOffice.ContinuousDatabase NuGet package.

Continuous Database Implementation

Before presenting how a DictionaryStep is applied to a physical database, this section defines two classes that represents the different stages of a DictionaryStep life. The lifecycle of a DictionaryStep is determined by its StepNumber, and is normally given a name that aligns with the feature. The DictionaryStep in this section is called DemoFeature, and like all DictionarySteps, must begin with a StepNumber set to 1.

DemoClass1 class creates one new table called Demo, sets table properties for replication, and finally defines nine add field methods. More than nine fields will be created, however. Can you spot the reason why?

Example DictionaryStep : DemoFeature, StepNumber 1

using SuperOffice.CD.DSL.V1.StepModel;
 
namespace ExampleDictionaryStep
{
    [Dictionary("DemoFeature", 1, ReleaseState.Released)]
    public class DemoClass1 : DictionaryStep
    {
        public override void Structure()
        {
            CreateTable("Demo", "Description of demo table", false, true)
                .TableProperties.Replication(ReplicationFlags.Up   | 
ReplicationFlags.Down | 
ReplicationFlags.Prototype)                 .AddBlob("BlobField", "Blogb field description")                 .AddBool("BoolField", "Boolean field description")                 .AddDateTime("DateTimeField", "Datetime field description")                 .AddDouble("DoubleField", "Double field description")                 .AddForeignKey("ForeignKeyField", "Foreign key field description", "contact")                 .AddInt("IntField", "Integer field description")                 .AddRegisteredUpdated()                 .AddString("StringField", "String field description", 256)                 .AddUShort("UIntField", "UintField description")                 ;         }     } }

With the assumption you are a partner building a product integration, which probably contains an uninstallation routine, a new class with the same Dictionary attribute is required to remove all changes. The DemoClassUninstall class is written to remove changes created by all previous DemoFeature DictionarySteps.

The way this DictionaryStep is distinguished from all other DemoFeature DictionarySteps is the StepNumber in the Dictionary Attribute. The StepNumber must be set to 2147483647, or in C# int.MaxValue.

When a DictionaryStep with StepNumber equal to int.MaxValue is applied, not only will the framework perform the commands in the Structure method to undo all changes, it will remove the DictionaryStepInfo from the DatabaseModel, ensuring no conflicts occur if or when the DictionaryStep StepNumber 1 is applied again in the future.

If you are still wondering why more than nine fields are created, AddRegisteredUpdated method is a macro method that adds several fields in one go! You can read more about these methods in the introductory article, Continuous Database.

Example DictionaryStep: DemoFeature, StepNumber int.MaxValue

using SuperOffice.CD.DSL.V1.StepModel;
 
namespace ExampleDictionaryStep
{
    [Dictionary("DemoFeature", int.MaxValue, ReleaseState.Released)]
    public class DemoClassUninstall : DictionaryStep
    {
        public override void Structure()
        {
            DropTable("Demo");
        }
    }
}

The only requirements to apply the DemoFeature StepNumber 1, and add the new table to the database, is:

  1. create a connection to the database,
  2. create an instance of the DatabaseManagement class,
  3. pass the DictionaryStep into the DatabaseManagement.ApplyDictionarySteps method.

The following code example resides in a new project - a console application, with the following assembly references:

  • the DictionaryStep assembly containing DemoClass1 and DemoClassUninstall - ExampleDictionaryStep.dll
  • SuperOffice.CD.DSL.dll
  • SuperOffice.CD.DSL.Implementation.dll):
private void ApplySteps()
{
    // populate database connection properties
    var ConnectionString = "Server=localhost;Database=SuperOffice81R;USER ID=crm7;Password=crm7myd";
    var Major = "MSSQL";
    var Minor = "14";
    var Prefix = "CRM7";

    // create connection to the database
    using (var connection = DbConnectionProvider.GetConnection(ConnectionString, Major, Minor))
    {
        // create a DatabaseManagement instance 
        using (var dbm = DatabaseManagement.CreateInstance(Prefix, connection))
        {
            // ensure this is a version 8.1 or higher database
            var dbState = dbm.InspectDatabase();
            if (dbState == DatabaseManagement.DatabaseContent.SuperOfficeCdd)
            {
                // get the database model - passed to DatabaseManagement for validation
                var model = dbm.ReadDatabaseModel();

                //prepare the list of DictionarySteps as a LinkedList
                var steps = new LinkedList<DictionaryStep>(new[] { new ExampleDictionaryStep.DemoClass1() });

                // apply the dictionary steps to the database model and physical database
                var result = dbm.ApplyDictionarySteps(steps, model);
            }
        }
    }
}

It’s that easy!

To remove the table, execute the same code but instantiate the DemoClassUninstall class and pass that into the LinkedList constructor instead.

Inside DatabaseManagement ApplyDictionarySteps

While it's not necessary to know how ApplyDictionarySteps works, it’s interesting to know what's going on under the hood to gain a better understanding of the architecture. 

The diagram below lists in sequence the actions that occur when a DictionaryStep is applied to a database.

This shows how a DictionarySteps is transformed into a command list by the CommandBuilder, and how the applicators use the command list to apply changes to the database. The diagram also details when priming actionas occur, when and where changes are logged to the database and the database model is persisted.

Conclusion

There are several things to think about when abstracting the evolutionary database concepts into an object-oriented methodology. It can easily become quite complex, without knowing how all the parts work together, but SuperOffice has made it simple and easy to make changes to the SuperOffice database. Infact, it's the same technology R&D teams uses for each SuperOffice iteration.

I hope this article has helped you learn how to apply your DictionarySteps and change the SuperOffice database to suit your needs.

To try this out for yourself, we have provided an example on GitHub

Post Comment To the top