Back to contents pageHow to implement the operations for a user-defined schema

How to implement the operations for a user-defined schema

Summary

This article shows how to create a schema server that implements the operations for a schema of a user-defined data model. The example implements the operations for the CarModule.CarData schema, whose assemblies were generated throughout the article How to create a user model using Data Dictionary.





Prerequisites

You should know the information in the following article:



Example material

Save this link to get a zip file of the example material


Guide

Adding the references to the assemblies

In the article How to create a user model using Data Dictionary we generated the assemblies for CarModule and CarModule.CarData. In this article we will continue working with these assemblies.


You need to ensure that assembly references point to the correct location. If you download the source code provided, CarModule.dll and CarModule-CarData.dll are assumed to be located in .\UserModel\CarModule_model_and_assemblies\ relative to the directory to which you extract the attached .zip file. Therefore, you need to generate the assemblies in that directory for the provided solution to work straight out of the box. Alternatively, you can download the generated libraries in the article How to create a user model using Data Dictionary. If you extract both .zip files to the same directory, the references will be found.


To implement the server in .NET you need to create a new console application. Then, reference the CarModule.dll assembly and the CarModule-CarData.dll schema assembly for the schema server that we are creating. It is usual to also reference UbisensePlatform.dll, which contains definitions that you are likely to use such as ICursor. The UbisensePlatform.dll file can be found in the directory where the Ubisense software was installed, in the bin folder (C:\Program Files\Ubisense 2.1\bin by default).



Creating the operation implementations

The CarModule.CarData schema has 3 operations to implement:



1) Create the implementation class

The CarModule.CarData schema assembly defines an interface Server, which contains methods for handling the remote operations that were defined in the user model and we should implement them in the server implementation. Each method implementation also has an additional parameter _schema which is the schema instance.


    class Operations: Ubisense.CarModule.CarData.Server
    {
        public bool get_car_properties(
            Ubisense.CarModule.CarData.Schema _schema,
            Ubisense.CarModule.Car car,
            out Ubisense.CarModule.CarData.CarProperties properties)
        {
            // implementation code goes here, see below
        }
        public bool set_car_properties(
            Ubisense.CarModule.CarData.Schema _schema,
            Ubisense.CarModule.Car car,
            Ubisense.CarModule.CarData.CarProperties properties)
        {
            // implementation code goes here, see below
        }
        public bool remove_car_properties(
            Ubisense.CarModule.CarData.Schema _schema,
            Ubisense.CarModule.Car car)
        {
            // implementation code goes here, see below
        }
    }



2) get_car_properties

This method returns the CarProperties record of a given Car object (via the out variable) if it finds it in the given schema's CarHasProperties relation. The following is a possible implementation:


    public bool get_car_properties(Ubisense.CarModule.CarData.Schema _schema,
        Ubisense.CarModule.Car car,
        out Ubisense.CarModule.CarData.CarProperties properties)
    {
        using (Ubisense.CarModule.CarData.ReadTransaction xact =
            schema.ReadTransaction())
        {
            Ubisense.UBase.ICursor<
                Ubisense.CarModule.CarData.CarHasProperties.RowType> cursor =
                Ubisense.CarModule.CarData.CarHasProperties.car_(xact, car);
            // if there is an entry in the table for the specified car
            if (cursor.MoveNext())
            {
                // return the properties in that entry
                properties = cursor.Current.car_properties_;
                return true;
            }
            // an entry with the specified car doesn't exist, there is nothing to return
            properties = new Ubisense.CarModule.CarData.CarProperties();
            return false;
        }
    }



3) set_car_properties

The set_properties_method creates an entry with the given Car and CarProperties objects. If an entry for that Car object already exists, it updates the car_properties_ field with the given CarProperties object:


    public void set_car_properties(
        Ubisense.CarModule.CarData.Schema _schema,
        Ubisense.CarModule.Car car,
        Ubisense.CarModule.CarData.CarProperties properties)
    {
        using (Ubisense.CarModule.CarData.WriteTransaction xact =
            _schema.WriteTransaction())
        {
            Ubisense.UBase.ICursor<
                Ubisense.CarModule.CarData.CarHasProperties.RowType> cursor =
                Ubisense.CarModule.CarData.CarHasProperties.car_(xact, car);
            // if the entry exists
            if (cursor.MoveNext())
            {
                // update the existing row with the given parameters
                Ubisense.CarModule.CarData.CarHasProperties.RowType row = cursor.Current;
                row.car_properties_ = properties;
                Ubisense.CarModule.CarData.CarHasProperties.Update(xact, cursor, row);
                xact.Commit();
            }
            else
            {
                // there was no entry for that Car create a new one
                Ubisense.CarModule.CarData.CarHasProperties.RowType row = new
                    Ubisense.CarModule.CarData.CarHasProperties.RowType(properties, car);
                Ubisense.CarModule.CarData.CarHasProperties.Insert(xact, row);
                xact.Commit();
            }
        }
    }



4) remove_car_properties

If an entry for the given Car object exists, this method removes it from the CarHasProperties relation.


    public bool remove_car_properties(Ubisense.CarModule.CarData.Schema _schema,
        Ubisense.CarModule.Car car)
    {
        using (Ubisense.CarModule.CarData.WriteTransaction xact =
            schema.WriteTransaction())
        {
            Ubisense.UBase.ICursor<
                Ubisense.CarModule.CarData.CarHasProperties.RowType> cursor =
                Ubisense.CarModule.CarData.CarHasProperties.car_(xact, car);
            // if the entry exists
            if (cursor.MoveNext())
            {
                // remove the row from the CarHasProperties relation
                Ubisense.CarModule.CarData.CarHasProperties.Delete(xact, cursor);
                xact.Commit();
                return true;
            }
            return false;
        }
    }



Starting the server

We can now use the schema operations implementation to attend the requests from schema clients. We will do this through a command line application that essentially just creates an instance of the schema, and connects to it as a server with the server implementation as an argument. The program then loops, calling the schema's Dispatch method.


    class Program
    {
        public static Ubisense.CarModule.CarData.Schema carDataSchema = new
            Ubisense.CarModule.CarData.Schema(false);

        static void Main(string[] args)
        {
            Operations ops = new Operations();
            carDataSchema.ConnectAsServer(ops, true, 0, 0);
            while (true)
            {
                carDataSchema.Dispatch(1000);
            }
        }
    }

With this, we are ready to run the server. Now, when a client application creates an instance of the CarData schema, it will be able to call its operations.



What's next?

This article covered the steps to implement a schema server. You are now ready to do each of the following 2 steps. You can create a service package in order to install the service to a dataset. You can create an application that is a client of the service. See the following articles:





Back to top