Skip to main content
InterSystems Supply Chain Orchestrator 2024.1
AskMe (beta)
Loading icon

Introduction to InterSystems IRIS Programming

This page provides a high-level introduction to applications in InterSystems IRIS® data platform, with emphasis on server-side code.

Introduction

InterSystems IRIS is a high-performance multi-model data platform with an implementation of SQL, known as InterSystems SQL, as well as built-in support for Python, and a general-purpose programming language called ObjectScript. InterSystems IRIS also provides support for class definitions; the procedural parts of a class can be implemented in Python or in ObjectScript. A set of system classes enable you to model objects and persistent objects (tables). Additional system classes provide a wide set of APIs.

InterSystems IRIS programming has the following features:

  • InterSystems IRIS supports multiple processes and provides concurrency control. Each process has direct, efficient access to the data.

  • Database storage is available directly via SQL, Python, and ObjectScript.

  • In all cases, stored data is ultimately contained in structures known as globals.

You can execute SQL, Python, and ObjectScript commands in a command-line shell, which is a useful tool to complement your IDE. You can also execute SQL in the Management Portal.

InterSystems IRIS supports Unicode data and localization.

Components of an InterSystems IRIS Application

From the point of view of an application developer, an InterSystems IRIS application consists of some or all the following elements on an InterSystems IRIS server:

  • An application definition, which controls access to the code.

    This controls things such as the allowed authentication mechanisms and the InterSystems IRIS namespace to start running the code in.

  • Any mix of InterSystems IRIS class definitions, routines, and include files that are available in that namespace. Classes and routines can be used interchangeably and can call each other. Include files provide central definitions for macros used within either classes or routines.

  • One or more namespaces, including the namespace in which the application starts running.

  • One or more databases, containing the data and code for the application.

  • External files as needed.

In InterSystems IRIS, you can access data directly from SQL, or classes, or routines, which means that you have the flexibility to store and access data exactly how you want.

Classes

InterSystems IRIS supports classes and object-oriented programming. You can use the system classes and you can define your own classes.

In InterSystems IRIS, a class can include familiar class elements such as properties, methods, and parameters (known as constants in other class languages). It can also include items not usually defined in classes, including triggers, queries, and indexes.

InterSystems IRIS class definitions use Class Definition Language (CDL) to specify the class and its members such as properties, methods, and parameters. You can use either Python or ObjectScript to write the executable code inside of methods. For each method, specify which language you will be writing the method in by using the Language keyword, as in the example below.

The following shows a class definition:

Class Sample.Employee Extends %Persistent
{

/// The employee's name.
Property Name As %String(MAXLEN = 50);

/// The employee's job title.
Property Title As %String(MAXLEN = 50);

/// The employee's current salary.
Property Salary As %Integer(MAXVAL = 100000, MINVAL = 0);

/// This method prints employee information using ObjectScript.
Method PrintEmployee() [ Language = objectscript] 
{
    Write !,"Name: ", ..Name, " Title: ", ..Title
}

}
Class Sample.Employee Extends %Persistent
{

/// The employee's name.
Property Name As %String(MAXLEN = 50);

/// The employee's job title.
Property Title As %String(MAXLEN = 50);

/// The employee's current salary.
Property Salary As %Integer(MAXVAL = 100000, MINVAL = 0);

/// This method prints employee information using Embedded Python.
Method PrintEmployee() [ Language = python ] 
{
    print("\nName:", self.Name, "Title:", self.Title)
}

}

If you do not specify which language a method uses, the compiler will assume that the method is written in ObjectScript.

Other topics provide more information on classes in InterSystems IRIS and the unique capabilities of persistent classes in InterSystems IRIS.

Routines

When you create routines in InterSystems IRIS, you use ObjectScript. The following shows part of a routine written in ObjectScript:

    SET text = ""
    FOR i=1:5:$LISTLENGTH(attrs)
    {
        IF ($ZCONVERT($LIST(attrs, (i + 1)), "U") = "XREFLABEL")
        {
            SET text = $LIST(attrs, (i + 4))
            QUIT
        }
    }
    
    IF (text = "")
    {
        QUIT $$$ERROR($$$GeneralError,$$$T("Missing xreflabel value"))
    }

Using Classes and Routines Together

In InterSystems IRIS, you can use classes from within routines. For example, the following shows part of a routine, in which we refer to the Sample.Employee class:

 //get details of random employee and print them
showemployee() public {
    set rand=$RANDOM(10)+1        ; rand is an integer in the range 1-10
    write "Your random number: "_rand
    set employee=##class(Sample.Employee).%OpenId(rand)  
    do employee.PrintEmployee()
    write !,"This employee's salary: "_employee.Salary
      
    }

Similarly, a method can invoke a label in a routine. For example, the following invokes the label ComputeRaise in the routine employeeutils:

Method RaiseSalary() As %Numeric
{
    set newsalary=$$ComputeRaise^employeeutils(..Salary)
    return newsalary
}
Method RaiseSalary() as %Numeric [ Language = python ]
{
    import iris
    newsalary=iris.routine("ComputeRaise^employeeutils", self.Salary)
    return newsalary
}

Globals

InterSystems IRIS supports a special kind of variable that is not seen in other programming languages; this is a global variable, which is usually just called a global. In InterSystems IRIS, the term global indicates that this data is available to all processes accessing this database. This usage is different from other programming languages in which global means “available to all code in this module.” The contents of a global are stored in an InterSystems IRIS database.

In InterSystems IRIS, a database contains globals and nothing else; even code is stored in globals. At the lowest level, all access to data is done via direct global access — that is, by using commands and functions that work directly with globals.

When you use persistent classes, you can create, modify, and delete stored data in the following ways:

  • In ObjectScript, using methods such as %New(), %Save(), %Open(), and %Delete().

  • In Python, using methods such as _New(), _Save(), _Open(), and _Delete().

  • In ObjectScript, using direct global access.

  • In Python, using the gref() method to provide direct global access.

  • By using InterSystems SQL.

Internally, the system always uses direct global access.

Programmers do not necessarily have to work directly with globals, but it can be helpful to know about them and the ways they can be used; see Introduction to Globals.

InterSystems SQL

InterSystems IRIS provides an implementation of SQL, known as InterSystems SQL. You can use InterSystems SQL within methods and within routines. Also, as noted previously, you can use SQL DDL commands to create tables (persistent classes).

Using SQL from ObjectScript

You can execute SQL from ObjectScript using either or both of the following ways:

  • Dynamic SQL (the %SQL.StatementOpens in a new tab and %SQL.StatementResultOpens in a new tab classes), as in the following example:

     SET myquery = "SELECT TOP 5 Name, Title FROM Sample.Employee ORDER BY Salary"
     SET tStatement = ##class(%SQL.Statement).%New()
     SET tStatus = tStatement.%Prepare(myquery)
     SET rset = tStatement.%Execute()
     DO rset.%Display()
     WRITE !,"End of data"
    

    You can use dynamic SQL in ObjectScript methods and routines.

  • Embedded SQL, as in the following example:

     &sql(SELECT COUNT(*) INTO :myvar FROM Sample.Employee)
        IF SQLCODE<0 {WRITE "SQLCODE error ",SQLCODE," ",%msg  QUIT}
        ELSEIF SQLCODE=100 {WRITE "Query returns no results"  QUIT}
     WRITE myvar

    The first line is embedded SQL, which executes an InterSystems SQL query and writes a value into a host variable called myvar.

    The next line is ordinary ObjectScript; it simply writes the value of the variable myvar.

    You can use embedded SQL in ObjectScript methods and routines.

Using SQL from Python

Using SQL from Python is similar to using Dynamic SQL from ObjectScript. You can execute SQL from Python using either or both of the following ways:

  • You can execute the SQL query directly, as in the following example:

    import iris
    rset = iris.sql.exec("SELECT * FROM Sample.Employee ORDER BY Salary") 
    for row in rset:
        print(row)
    
    

    The second line executes an InterSystems SQL query and returns a result set stored in the variable rset.

  • You can also prepare the SQL query first, then execute it, as in the following example:

    import iris
    statement = iris.sql.prepare("SELECT * FROM Sample.Employee ORDER BY Salary")
    rset = statement.execute()
    for row in rset:
        print(row)
    
    

    In this example, the second line returns a SQL query which is executed on the third line to return a result set.

You can use either of these approaches to execute SQL queries in the Python terminal or in Python methods.

Macros and Include Files

ObjectScript also supports macros, which define substitutions. The definition can either be a value, an entire line of code, or (with the ##continue directive) multiple lines. You use macros to ensure consistency. For example:

 #define StringMacro "Hello, World!"

 write $$$StringMacro

You can define macros in a routine and use them later in the same routine. More commonly, you define them in a central place. To do this, you create and use include files. An include file defines macros and can include other include files. For details, see Using Macros and Include Files.

The phrase include file is used for historical reasons. In InterSystems IRIS, an include file is not actually a separate standalone file in the operating system; instead it is a unit of code stored within an InterSystems IRIS database.

Location of Code

In InterSystems IRIS, class definitions, routines, and include files are stored within an InterSystems IRIS database. Your IDE provides options for editing this code and synchronizing with your choice of source control system.

How These Code Elements Work Together

It is useful to understand how InterSystems IRIS uses the code elements introduced in this page.

The reason that you can use a mix of ObjectScript, Python, InterSystems SQL, class definitions, macros, routines, and so on is that InterSystems IRIS does not directly use the code that you write. Instead, when you compile your code, the system generates lower-level code that it uses. This is OBJ code for ObjectScript, used by the ObjectScript engine, and PYC code for Python, used by the Python engine.

There are multiple steps. It is not necessary to know the steps in detail, but the following points are good to remember:

  • The class compiler processes class definitions and ObjectScript code into INT code for all elements other than Python methods. Python code is processed into PY code.

    In some cases, the compiler generates and saves additional classes, which you should not edit. This occurs, for example, when you compile classes that define web services and web clients.

    The class compiler also generates the class descriptor for each class. The system code uses this at runtime.

  • For ObjectScript code, a preprocessor (sometimes called the macro preprocessor or MPP) uses the include files and replaces the macros. It also handles the embedded SQL in routines.

    These changes occur in a temporary work area, and your code is not changed.

  • Additional compilers create INT code for routines.

  • INT code and PY code are an intermediate layer in which access to data is handled via direct global access. This code is human-readable, and you can see it within your IDE.

  • INT code is used to generate OBJ code, and PY code is used to generate PYC code. The InterSystems IRIS virtual machine uses this code. Once you have compiled your code into OBJ and PYC code (the final code), the INT and PY routines are no longer necessary for code execution.

  • After you compile your classes, you can put them into deployed mode. InterSystems IRIS has a utility that removes the class internals and the intermediate code for a given class; you can use this utility when you deploy your application.

    If you examine the InterSystems IRIS system classes, you might find that some classes cannot be seen because they are in deployed mode.

The intermediate code and the final code are contained in the same database that contains the code from which it was generated.

FeedbackOpens in a new tab