.NET Language Server Test DLL

The .NET Language Server (DNLS) distribution includes a test DLL, DBOTestDLL.dll, which is installed in the same folder as the DNLS service executable, DBOService.exe, which is typically:

C:\Program Files\Reality\DBO

The source code, at the time of writing, is reproduced at the end of this section.

This DLL can be used to test various features of .NET DataBasic objects.

Testing

Objects

There is no limitation by DataBasic on the use of underlying objects. DBO variables are object references which can be passed around in the same way as normal variables and they can even be passed in and out of methods invoked on an object.

TestObject = LANG.SVR->%New("DBOTestDLL.DboTest")
TestObject2 = TestObject->NewDbo("DboTest - 2", "Purple") ;* (Note 1)
Colour = TestObject2->GetColour(TestObject2)              ;* (Note 2)
IF Colour # "Purple" THEN
   CRT "Failed"
END
  1. The TestObject.NewDbo() method is invoked which creates a new DboTest object and returns a reference to that object, TestObject2.

  2. The method TestObject2.GetColour() method is invoked and a reference to TestObject2 itself is passed as a parameter. GetColour() returns the Colour field from the supplied object.

Properties and fields

.NET language classes have two slightly different types of data accessor: properties and fields. The data value of a field can be read and written directly but each property is accessed by means of intermediate setters and getters (for example, get and set accessors for C#) that allow additional processing such as validation.

As far as DataBasic is concerned a property's get and set accessors are implicit, so both properties and fields are accessed identically. For example, DboTest.Colour is a property and DboTest.Name is a field:

TestObject = LANG.SVR->%New("DBOTestDLL.DboTest","Bloggs","Green")
IF TestObject->Colour # "Green" OR TestObject->Name # "Bloggs" THEN
   CRT "Failed"
END

Arrays of primitive data types

You can create an one-dimensional array of primitive data types in DataBasic by applying the %Array special method to a connection object and specifying the data type and the initial element values, either by a comma separated list or by a dynamic array. The result is an array object which can referenced by a DBO variable in the usual way.

Underlying arrays can be accessed element by element on the array object, for example:

TestObject = LANG.SVR->%New("DBOTestDLL.DboTest")
NoOfElements = 4 ;* Number elements in TestObject->StrVector[]
Vector = TestObject->StrVector ;* Array of strings
IF Vector->Length # NoOfElements THEN
   CRT "Failed"
END
Values = ""
FOR I = 1 TO NoOfElements
   Values<I> = "New Value=":I
   TestObject->StrVector[I - 1] = Values<I>
NEXT I
FOR I = 1 TO NoOfElements
   IF Vector->@Element[I - 1] # Values<I> THEN
      CRT "Failed"
   END
NEXT I

Arrays of objects

A DBO variable can refer to an array of objects. The @Element pseudo-field can be used to access each one, and these can be assigned to other DBO variables.

TestObject = LANG.SVR->%New("DBOTestDLL.DboTest")
NoOfElements = 7
TestObject.Array = TestObject->GetObjArray(NoOfElements);
IF TestObject.Array->Length # NoOfElements THEN
   CRT "Fail"
END
FOR I = 0 TO NoOfElements - 1
   TestObject.Element = TestObject.Array->@Element[I]
   IF TestObject.Element->Offset # I THEN
      CRT "Fail"
   END
NEXT I
* Shuffle the elements of TestObject.Array [0..6] to [6, 0..5]
TestObject.Element = TestObject.Array->@Element[0]
FOR I = 0 TO NoOfElements - 2
   TestObject.Array->@Element[I] = TestObject.Array->@Element[I+1]
NEXT I
TestObject.Array->@Element[NoOfElements-1] = TestObject.Element

Calling object methods

The .NET programming languages support what is referred to as method signatures or overloading whereby there may be two or methods of the same name but with different parameter lists. The DNLS can determine which method is being called from DataBasic by matching both the method name and the number and types of the parameters provided.

For example DBOTestDLL defines two ArrayLength() methods, one of which takes an array of strings and the other an array of objects.

TestObject = LANG.SVR->%New("DBOTestDLL.DboTest")
TestObject.Array = TestObject->StrVector          ;* String[]
IF TestObject->ArrayLength(TestObject.Array) # TestObject.Array->Length THEN
   CRT "Fail"
END
TestObject.Array = TestObject->GetObjArray(7)      ;* DboTest[]
IF TestObject->ArrayLength(TestObject.Array) # TestObject.Array->Length THEN
   CRT "Fail"
END

Static properties, fields and methods

These are methods, properties and fields that are not specific to any instantiated object of a given class but rather a persistent element of the class itself. In a .NET programming language one would reference a static element by the class name rather than the name of a particular object.

The DNLS supports a %Class special method (and a synonym, %Static) by which DataBasic can access the static elements of a class. For example, the DBOTestDLL.DboTest class defines the DefaultColour static property.

TestObject = LANG.SVR->%Class("DBOTestDLL.DboTest")
TestObject->DefaultColour = "Green"
IF TestObject->DefaultColour # "Green"
    CRT "Fail"
END

DBOTestDLL.dll

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DBOTestDLL
{
    /*****************************************************************
     * 
     * DboTest Class - To test creating and accessing DBOs
     * 
     *****************************************************************/
    class DboTest
    {
        public static string DefaultName = "default";
        private static string _defaultColour = "black";
        public string Name;
        private string colour;
        public int Offset;
        public Single FltOffset;
        public string[] StrVector = new string[4];
        public static string[] StaticVector = new string[4];

        /* To test access to static property */

        public static string DefaultColour
        {
            get { return _defaultColour; }
            set { _defaultColour = value; }
        }

        /* To test static method to access static field */
        public static string GetDefaultColour()
        {
            return (_defaultColour);
        }

        public DboTest()
        {
            Name = DboTest.DefaultName;// Note is accessed as a field
            colour = DboTest._defaultColour;
            Offset = 0;
        }

        public DboTest(int n)
        {
            Offset = n;
        }

        public DboTest(Single n)
        {
            FltOffset = n;
        }

        public DboTest(string n, string c)
        {
            Name = n;
            colour = c;
            Offset = 0;
        }

        // Colour property

        public string Colour          // And is accessed as a property
        {
            get { return colour; }
            set { colour = value; }
        }

        public String GetColour()
        {
            return (Colour);
        }

        public int Add(int val1)
        {
            int result;
            result = val1 + Offset;
            return (result);
        }

        public int Add(int val1, int val2)
        {
            int result;
            result = val1 + val2 + Offset;
            return (result);
        }

        public Double Add(Single val1, Double val2)
        {
            Single result;
            result = val1 + (Single)val2 + FltOffset;
            return (result);
        }

        public Boolean ReturnArg(Boolean arg)
        {
            return (arg);
        }

        public Char ReturnArg(Char arg)
        {
            return (arg);
        }

        public Int16[] GetArray()
        {
            Int16[] result;
            int i;

            result = new Int16[7];
            for (i = 0; i < 7; i++)
                result[i] = (Int16)i;

            return (result);
        }

        public DboTest NewDbo(string n, string c)
        {
            DboTest newDbo = new DboTest(n, c);
            return (newDbo);
        }

        /* This will be used to return an array of objects */

        public DboTest[] GetObjArray(Int32 len)
        {
            DboTest[] result;
            int i;

            result = new DboTest[len];
            for (i = 0; i < len; i++)
                result[i] = new DboTest(i);

            return (result);
        }

        /* ArrayLength will be used to test the passing of an object
         * array as an argument to a method */

        public Int32 ArrayLength(String[] array)
        {
            return (array.Length);
        }

        public Int32 ArrayLength(DboTest[] array)
        {
            return (array.Length);
        }

        /* This will be used to prove that can call method on Dbo
         * from NewDbo plus that DBOs can be passed as parameters
         * in method calls */

        public String GetColour(DboTest dboTest)
        {
            return (dboTest.Colour);
        }
    }
}