docs.intersystems.com
Home / Using the InterSystems Native API for .NET / Introduction to the Native API

Using the InterSystems Native API for .NET
Introduction to the Native API
Previous section           Next section
InterSystems: The power behind what matters   
Search:  


The Native API for .NET is a lightweight interface to the native multidimensional storage data structures that underlie the InterSystems IRIS™ object and SQL interfaces. The Native API allows you to implement your own data structures by providing direct access to global arrays, the tree-based sparse arrays that form the basis of the multidimensional storage model. The Native API for .NET is implemented in the IrisClient.ADO.IRIS class as an extension to the InterSystems Managed Provider for .NET (see Using the InterSystems Managed Provider for .NET).
This chapter discusses the following topics:
Introduction to Global Arrays
A global array, like all sparse arrays, is a tree structure rather than a sequentially numbered list. The basic concept behind global arrays can be illustrated by analogy to a file structure. Each directory in the tree is uniquely identified by a path composed of a root directory identifier followed by a series of subdirectory identifiers, and any directory may or may not contain data.
Global arrays work the same way: each node in the tree is uniquely identified by a node address composed of a global name identifier and a series of subscript identifiers, and a node may or may not contain a value. For example, here is a global array consisting of five nodes, two of which contain values:
   root -->|--> foo --> SubFoo="A"
           |--> bar --> lowbar --> UnderBar=123
Values could be stored in the other possible node addresses (for example, root or root->bar), but no resources are wasted if those node addresses are valueless. In InterSystems globals notation, the two nodes with values would be:
   ^root("foo","SubFoo")
   ^root("bar","lowbar","UnderBar")
In this notation, the circumflex (^) is a symbol indicating that this is a global array. This is followed by the global name (root) and a comma-delimited subscript list in parentheses, specifying the entire path to the node. This global array could be created by two calls to the Native API Set() method:
  native.Set("A","root","foo","SubFoo");
  native.Set(123,"root","bar","lowbar","UnderBar");
Global array root is created when the first call assigns value "A" to node ^root("foo","SubFoo"). Nodes can be created in any order, and with any set of subscripts. The same global array would be created if we reversed the order of these two calls. The valueless nodes are created automatically (and will be deleted automatically when no longer needed. For details, see Creating, Updating, and Deleting Nodes in the next chapter).
The Native API code to create this array is demonstrated in the following example. An IRISConnection object connects to the server and creates an instance of class IRIS, which implements the Native API. IRIS methods create a global array, read the resulting persistent values from the database, and then delete the global array.
The NativeDemo Program
The Native API for .NET is part of the InterSystems.Data.IrisClient.dll library. For detailed information on installation and usage, see the Introduction to Using the InterSystems Managed Provider for .NET.
using System;
using InterSystems.Data.IRISClient;
using InterSystems.Data.IRISClient.ADO;

namespace NativeSpace {
  class NativeDemo {
    static void Main(string[] args) {
      try {

//Open a connection to the server and create an IRIS object
        IRISConnection conn = new IRISConnection();
        conn.ConnectionString = "Server = localhost; "
        + "Port = 51773; " + "Namespace = USER; "
        + "Password = SYS; " + "User ID = _SYSTEM;";
        conn.Open();
        IRIS native = IRIS.CreateIRIS(conn);

//Create a global array in the USER namespace on the server
        native.Set("A", "root", "foo", "SubFoo");
        native.Set(123, "root", "bar", "lowbar", "UnderBar");

// Read the values from the database and print them
        string subfoo = native.GetString("root", "foo", "SubFoo");
        string underbar = native.GetString("root", "bar", "lowbar", "UnderBar");
        Console.WriteLine("Created two values: \n"
          + " ^root(\"foo\",\"SubFoo\")=" + subfoo + "\n"
          + " ^root(\"bar\",\"lowbar\",\"UnderBar\")=" + underbar);

//Delete the global array and terminate
        native.Kill("root"); // delete global array ^root
        native.Close();
        conn.Close();
      }
      catch (Exception e) {
        Console.WriteLine(e.Message);
      }
    }// end Main()
  } // end class NativeDemo
}
NativeDemo prints the following lines:
Created two values:
   ^root("foo","SubFoo")=A
   ^root("bar","lowbar","UnderBar")=123
In this example, an IRISConnection object named conn provides a connection to the database associated with the USER namespace. Native API methods perform the following actions:
The next chapter provides detailed explanations and examples for all of these methods.
Glossary of Native API Terms
See earlier sections of this chapter for an overview of the concepts listed here. Examples in this glossary will refer to the global array structure listed below. The ^Legs global array has ten nodes and three node levels. Seven of the ten nodes contain values:
  Legs                       // root node, valueless, 3 child nodes
    fish = 0                 // level 1 node, value=0
    mammal                   // level 1 node, valueless
      human = 2              // level 2 node, value=2
      dog = 4                // level 2 node, value=4
    bug                      // level 1 node, valueless, 3 child nodes
      insect = 6             // level 2 node, value=6
      spider = 8             // level 2 node, value=8
      millipede = Diplopoda  // level 2 node, value="Diplopoda", 1 child node
        centipede = 100      // level 3 node, value=100
Child node
The nodes immediately under a given parent node. The address of a child node is specified by adding exactly one subscript to the end of the parent subscript list. For example, parent node ^Legs("mammal") has child nodes ^Legs("mammal","human") and ^Legs("mammal","dog").
Global name
The identifier for the root node is also the name of the entire global array. For example, root node identifier Legs is the global name of global array ^Legs. The circumflex ^ is not part of the identifier; it is an ObjectScript convention to indicate that we are talking about a node address.
Node
An element of a global array, uniquely identified by a namespace consisting of a global name and an arbitrary number of subscript identifiers. A node must either contain data, have child nodes, or both.
Node level
The number of subscripts in the node address. A ‘level 2 node’ is just another way of saying ‘a node with two subscripts’. For example, ^Legs("mammal","dog") is a level 2 node. It is two levels under root node ^Legs and one level under ^Legs("mammal").
Node address
The complete namespace of a node, including the global name and all subscripts. In ObjectScript notation, a node address is written as a circumflex (^) followed by the root node identifier and an optional list of subscripts in parentheses. For example, node address ^Legs(fish) consists of root node identifier Legs plus a list containing one subscript, fish. Depending on context, ^Legs (with no subscript list) can refer to either the root node address or the entire global array.
Root node
The node with no subscripts at the base of the global array tree (see Global name).
Subnode
All descendants of a given node are referred to as subnodes of that node. For example, node ^Legs("bug") has four different subnodes on two levels. All nine subscripted nodes are subnodes of root node ^Legs.
Subscript / Subscript list
All nodes under the root node are addressed by specifying the global name and a list of one or more subscript identifiers (see Node address).
Target address
Many Native API methods require you to specify a valid node address that does not necessarily point to an existing node. For example, the set() method takes a value argument and a target address, and stores the value at that address. If no node exists at the target address, a new node is created.
Value
A node can contain a value of any supported type. A node with no child nodes must contain a value; otherwise the value is optional.
Valueless node
A node must either contain data, have child nodes, or both. A node that has child nodes but does not contain data is called a valueless node.


Previous section           Next section
View this book as PDF   |  Download all PDFs
Copyright © 1997-2019 InterSystems Corporation, Cambridge, MA
Content Date/Time: 2019-04-10 14:45:55