InterSystems Caché Technology Guide

Chapter Three:
Caché's Application Server

The Caché Application Server offers advanced object programming capabilities, provides sophisticated data caching, and integrates easy access to a variety of technologies. The Caché Application Server makes it possible to develop sophisticated database applications rapidly, operate them with high performance, and support them easily.

More specifically, the Caché Application Server provides:

  • The Caché Virtual Machine which runs three built-in scripting languages – Caché ObjectScript, Caché Basic, and Caché MVBasic.
  • Access to Caché Multidimensional Data Servers on the same and other computers with transparent routing.
  • Connectivity software with client-side caching to permit rapid access to Caché objects from all commonly used technologies, including Java, C++, C#, COM, .NET, and Delphi. Caché automatically performs the networking between the client and application server.
  • Compatibility with SOAP and XML.
  • SQL access using ODBC and JDBC, including sophisticated caching at the client and application server for high performance.
  • Access to relational databases.
  • Caché Server Pages for high-performance, easy-to-program Web applications.
  • Caché Studio – an IDE to rapidly develop and debug applications with Caché.
  • Code for the scripting languages is stored in the database and can be changed online, with changes automatically propagating to all application servers.

THE CACHÉ VIRTUAL MACHINE AND SCRIPTING LANGUAGES

The core of the Caché Application Server is the extremely fast Caché Virtual Machine, which supports Caché’s scripting languages.

  • Caché ObjectScript is a powerful and easy-to-learn object-oriented language with extremely flexible data structures.
  • Caché Basic provides an easy way for Visual Basic programmers to start using Caché. Similar to VBScript, Caché Basic supports objects and is extended to have direct access to the Caché Multidimensional Arrays.
  • Caché MVBasic is the variant of the Basic programming language used in MultiValue (Pick) applications. MVBasic has been extended to support objects and have direct access to the Caché Multidimensional Arrays.

Database access within the Caché Virtual Machine is highly optimized. Each user process in the Caché Virtual Machine has direct access to the multidimensional data structures by making calls to shared memory that access a shared database cache. All other technologies (Java, C++, ODBC, JDBC, etc.) connect through the Caché Virtual Machine to access the database.

Complete Interoperability

Since Caché ObjectScript, Basic, and MVBasic are all implemented on the same Caché Virtual Machine, they are completely interoperable:

  • Any object method can be written in any language – the same class can use all three languages.
  • Each language’s function calls can access code written in the other languages.
  • They share variables, arrays, and objects.

Faster Development/Flexible Deployment

In almost all cases, programmers can develop applications faster, and those applications will run significantly faster with greater scalability, by writing as much code as possible in these scripting languages so that they run in the Caché Virtual Machine. Plus, such code requires no changes to switch hardware or operating systems. Caché automatically handles all differences in operating systems and hardware.

Scripting Languages
A Failover Cluster

 

THE CACHÉ ADVANTAGE

Rapid Application Development: Development of complex database applications with Caché ObjectScript is radically faster than any other major language – often 10 to 100 times faster. Faster also means the project has a better chance of succeeding – with fewer programmers – and being able to adjust rapidly as the application needs to change.

Shorter Learning Curve: Basic is perhaps the world's best-known computer language. Developers who know Visual Basic can instantly start writing code in Basic, and the Caché object model is easily learned.

Faster and More Scalable: The Caché Virtual Machine with its direct access to the database provides faster applications that can scale to tens of thousands of users using low-cost hardware.

Flexibility: Code that runs in the Caché Virtual Machine can run on other hardware and operating systems without change. Code is stored in the database and automatically propagated to application servers.


CACHÉ OBJECTSCRIPT

Caché ObjectScript is a powerful, object-oriented programming language designed for rapid development of database applications. Here are some of the key characteristics of the language.

Overall Structure

Caché ObjectScript is command-oriented; hence it has syntax such as:

set x=a+b
do rotate(a,3)
if (x>3)

There is a set of built-in system functions that are particularly powerful for text manipulation. Their names all start with the single “$” character to distinguish them from variable and array names. For example:

$extract(string,from,to)  

// get a set of characters from a string

$length(string)

// determine the length of a string

Expressions use left-to-right operator precedence, just like most hand-held calculators, except when parentheses alter the order of evaluation.

Flexible Data Storage

One of the most unique characteristics of Caché ObjectScript is its highly flexible and dynamic data storage. Data may be stored in:

  • Object properties
  • Variables
  • Sparse, multidimensional arrays that permit any type of data for subscripts
  • Database files (“globals”) which are sparse multidimensional arrays
  • With rare exceptions, any place in the language where a variable can be used, an array, object property, or global reference could also be used.

In most computer languages, datatypes are an extension of hardware storage concepts (integer, float, char, etc.). However, Caché ObjectScript has the philosophy that humans don’t think using such storage types, and that these “computer-centric” datatypes simply impede rapid application development. Requiring declarations and dimension statements introduces far more errors than they help prevent (e.g., errors such as a 2-byte integer overflow, or when a string overflows its allocation of memory and corrupts other storage). However, object typing, such as Person, Invoice, or Animal, is viewed as highly valuable and consistent with the way humans think.

Thus, in Caché ObjectScript, object properties are strongly typed, but the other three types of storage (variables, arrays, and global nodes) are fully polymorphic, typeless entities that need not be declared or defined. They simply pop into existence as they are used and mold themselves to the data needs of what they are storing and how they are being used in an expression. Even arrays do not need any specification of size, dimension, type of subscripts, or data. For example, a developer might create an array called Person by simply setting:

set Person(”Smith”,”John”)=”I’m a good person”

In this example, data was stored in a two-dimensional array using string data for subscripts. Other data nodes in this array might have a different number of dimensions and might intermix strings, integers, or other types of data for subscripts. For example, one might store data in:

abc(3)
abc(3,-45.6,”Yes”)
abc(”Count”)

all in the same array.

Direct Access to the Database

Direct AccessA direct reference to the database (a “global reference”) is essentially a multidimensional array reference preceded by the carat character “^”. That character indicates this is a reference to data stored in the database rather than to temporary process private data. Each such database array is called a “global”.

As with multidimensional arrays and variables, no declarations or definitions or reservations of storage are required to access or store data in the database; global data simply pops into existence as data is stored. For example, to store information in the database one might write:

set ^Person(“Smith”,”John”)=”I’m a very good person”

and later might retrieve it by code such as:

set x=^Person(“Smith”,”John”)

The programmer has complete flexibility in how to structure these global data arrays.
(See the Multidimensional Data Model.)

Object References

Caché objects implement the ODMG data model, with powerful extensions.

In Caché ObjectScript, an “oref” is used to access an object. (An oref is typically a variable whose value specifies which in-memory object is being referenced.) The oref is followed by a dot and then by the name of a property or method. Object references can be used wherever an expression can be used. For example:

set name=person.Name

// 'person' is a variable whose value is an oref

// the person’s name is put into
// the variable ‘name’

if (person.Age>x)

// see if the person’s age is
// greater than ‘x’

set money=invoice.Total()

// ‘Total()’ is a method that
// calculates the sum of

// all of the invoice’s
// line items

Methods can also be executed with a DO command when no return value is needed. For example:

do part.Increment()

// ‘Increment()’ is a method whose
// return value, if any,
// is not of interest

The oref is not the same as a database object ID. The object ID is a value that is permanently associated with a database object; it is used to retrieve and store a database object. Once an object is in memory, it is assigned a reusable oref value that is then used to access the object’s data. The next time that same database object is brought into memory it will probably be assigned a different oref value.

Caché Technology Guide

HTML and SQL Access

HTML for Web applications and SQL can be embedded in Caché ObjectScript code.

Calling Code

In some object languages, all code has to be part of some method. Caché ObjectScript doesn’t have that restriction – code may be directly called or called through object syntax.

Code is often called using the DO command.

do rotate(a,3)

Code that returns a value can also be called as a function. For example,

set x=a+$$insert(3,y)

calls the programmer-written procedure or subroutine “insert”.

Code can also be invoked as an object method.

set money=invoice.Total()

// Total() returns the

// invoice total amount due

part.Increment()

// ‘Increment()’ is a method

// whose return value,

// if any, is not of interest

Both call by value and call by reference is supported for parameters.

Routines

Caché ObjectScript code is fundamentally organized into a set of “routines”. Each routine (typically up to 32KB in size) is atomic in the sense that it can be independently edited, stored, and compiled. Routines are linked dynamically at run time; there is no separate linking step for the programmer. Routine code is stored in the database; thus, routines can be dynamically paged across the network rather than having to be installed on each computer.

Within a routine, code is organized as a set of procedures and/or subroutines. (An object method is a procedure, but it is accessed by a different syntax.)

When calling code that is within the same routine, only the procedure or subroutine name is needed. Otherwise, the routine name must be appended to it.

do transfer()

// calls ‘transfer’ in
// the same routine

do total^invoice()

// calls ‘total’ in the
// routine "invoice"

A procedure or subroutine that has a return value of interest should be called using the “$$” function syntax.

set x=$$total^invoice()

// calls the same ‘total’
// procedure but uses the
// return value

Routines can be edited and compiled through the Caché Studio.

Caché Technology Guide

Object Methods

Class definitions and their method codes are stored in global data files, and the Class Compiler compiles each class into one or more routines. Each method is simply a procedure in a routine, although it can only be invoked by object syntax. For instance, if the Patient class defines an Admit method and the Pat variable identifies a specific Patient object, then we call the Admit method for that object with the following syntax:

do Pat.Admit()

// Call the admit method
// for Patient

set x = Pat.Admit()

// Calls the same method
// but uses the return value

Procedures and Public/Private Variables

A procedure is a block of code within a routine that is similar to a function in other languages. A procedure consists of a name, a formal parameter list, a list of public variables, and a block of code delimited by “{}”. For example:

Admit(x,y)[name,recnum] { ...code goes here}

In Caché ObjectScript, some variables are public (common) and others are private to a particular procedure. Every variable that is used within a procedure is considered private to that procedure unless it is listed in the public list. In the above example, “name” and “recnum” access the public variables by those names, whereas all other variables exist only for this invocation of this procedure. Variable names that start with a “%” character are always implicitly public.

Procedures cannot be nested, although a procedure can contain subroutines.

Subroutines

SubroutinesRoutines may also contain subroutines, which are lighter weight than procedures. A subroutine may contain a parameter list and it may return a value, but it does not have a public list or formal block structure. Subroutines may be embedded within procedures or be at the same level as a procedure in a routine.

Subroutines permit the calling of code using the same public/private set of variables as the caller, and they can be called quicker. A subroutine embedded within a procedure uses the same variable scope as the procedure and may only be called from within that procedure. Variable references in a subroutine that is not part of a procedure are all to public variables.

BASIC

Basic is perhaps the world’s best-known application programming language. In Caché, Basic has been extended to support direct access of the Data Server’s core data structures – multidimensional arrays – as well as other Caché Application Server features. It directly supports the Caché ObjectModel using Visual Basic syntax, and runs in the Caché Virtual Machine.

Basic can be used either as methods of classes or as Caché routines (see the Caché ObjectScript description of routines). Basic can call Caché ObjectScript, and vice versa, with both languages accessing the same variables, arrays, and objects in process memory.

Arrays have been extended to be far more powerful:

  • The presence of a "^" character preceding the array name indicates a reference to a database multidimensional array – persistent arrays that are shared with other processes.
  • Subscripts can be of any datatype – strings, integers, decimal numbers, etc.
  • Data can be stored at multiple subscript levels in the same array – for example, data could be stored at A(“colors”)  and A(“colors”,3).
  • Arrays do not have to be declared and they are always sparse – Caché only reserves space as nodes are inserted.
  • A Traverse function allows identification of the next (or previous) subscript at a given subscript level.

Other extensions include:

  • Transaction processing commands to Start, Commit, and Rollback a transaction.
  • An atomic increment function that can be used on the database.
  • Extensions that provide better integration with the Caché Application Server capabilities.

Object Access with Basic

In Caché, classes are organized into packages, and class names include the package name followed by a period. For example, Payroll.Person is a Person class of the Payroll package. The Basic New command is used to create an object:

person = New Payroll.Person()

// creates a new
// Person object

Basic has been extended with an OpenID command to access an existing object:

person = OpenID Payroll.Person(54)

// opens the Person
// object with
// Object ID 54

Here are some examples of code that access the person’s properties:

person.Name = ”Smith, John”

// sets the person’s name

person.Home.City

// references the
// person’s home city

person.Employer.Name

// brings the person’s
// employer object into

// memory and accesses
// the employer’s name

Database classes can be saved to disk with the Save method. For example:

person.Save()

will save the person, creating an object ID if it is the first time the object was stored. If related objects (such as the Employer) were also modified, they are automatically saved as well.

Caché Technology Guide

 

MVBASIC

MVBasic is another scripting language offered in Caché that is a variant of Basic. However, it is intended to execute applications written for MultiValue (Pick) systems and therefore supports additional characteristics, including capabilities to access and manipulate MultiValue files.

MVBasic can be used either as methods of classes or as Caché routines (see the Caché ObjectScript description of routines). MVBasic can call Caché ObjectScript or Basic, and vice versa, with all three languages accessing the same variables, arrays, and objects in process memory.

Caché MVBasic has the same extensions as Caché Basic, including object access. However, because of possible ambiguity, the two character sequence “->” is used instead of using a period separator “.” in object references.

C++

Every Caché class can be projected as a C++ class, with methods corresponding to each property and method of the Caché class. To C++ programs, these classes look just like any other local C++ classes, and Caché automatically handles all communications between the client and server. Properties of the class are cached on the client, and C++ method calls invoke corresponding server side methods, including methods to store an object in the database and later retrieve it.

JAVA

Java is a popular programming language, but connecting Java applications to most databases can be challenging. Connecting to a relational database requires extensive coding of SQL – which is very time-consuming and blunts many of the advantages of Java’s object technology. Caché’s approach of directly storing objects without the developer worrying about how the data will be persisted and using object syntax to access the database is much simpler – and usually preferred.

Java Supported Several Ways
Caché & Java Access

Some developers want to work exclusively with “plain old Java objects” (POJOs), while others prefer Enterprise Java Beans (EJB). Also, some developers prefer to first define the database schema and then automatically generate a corresponding Java class for each database class, while others prefer to first create Java classes and have Caché automatically generate a database schema. Caché supports all of these approaches:

  • Any Caché class can be projected as a Java class so properties and methods can be accessed as Java objects.
  • Caché classes can also be projected as Enterprise Java Beans.
  • JDBC provides high-performance SQL access using a completely Java-based (Type 4) driver.
  • InterSystems Jalapeño™ technology creates Caché classes from POJO class descriptions.

Object Access Through Projected Classes

Every Caché class can be projected as a Java (or EJB) class, with methods corresponding to every property and method of the Caché class. To Java programs, these classes look just like any other local Java classes. The generated Java class uses a Java library provided by InterSystems to handle all communications between the client and server.

State for every Caché object is maintained in the Caché Application Server, although properties of the class are also cached in the client to optimize performance. Java method calls invoke corresponding methods on the Caché Application Server – including methods to store an object in the database and later retrieve it. It is transparent to the client as to which Caché Data Server contains the data, or even if the object data is stored in a relational database accessed through the Caché Application Server.

Caché Methods Written in Java

Methods of Caché classes can be written in Java using Caché Studio. However, unlike Caché ObjectScript and Basic, Java methods are not executed by the Caché Virtual Machine. Instead, they are included in the generated Java class and executed in any Java Virtual Machine. Such code is not accessible from non-Java methods.

Providing Persistence for J2EE Applications

Developers of J2EE applications, which use Enterprise Java Beans (EJB), work primarily with objects until such time as they need to access the database. Then, they are usually forced to revert to using SQL. Through its JDBC interface, Caché can provide extremely fast SQL response to such applications. However, SQL access is not generally the preferred approach.

Object databases represent a more natural access technique to EJB programmers. Caché projects Caché classes as EJBs, automatically generating highperformance persistence methods for Bean-Managed Persistence (BMP). This avoids the overhead of SQL and object-relational mapping – the result is higher scalability for J2EE applications.

Jalapeño technology can also be used in J2EE applications with the same advantages.

Jalapeño Allows Java-in Development

Instead of starting with Caché classes and projecting them as Java components, Jalapeño technology does the opposite. It allows Java developers to define object classes within whatever Java development environment they favor and automatically persist those classes in Caché. The developer’s Java class is unchanged – Caché provides a library class with an API that is used to store and retrieve objects and issue queries for the developer’s classes.

THE CACHÉ ADVANTAGE

Flexibility: Java developers have choices when it comes to accessing Caché objects – they can use SQL and JDBC or more naturally project objects such as Java classes or Enterprise Java Beans. With Jalapeño, developers have the option of working entirely within their favorite Java development environment and letting Caché automatically provide methods to store and retrieve objects from the database without touching the developer’s classes.

High Performance: All Java applications, regardless of how they are connected to Caché, benefit from Caché’s superior performance and scalability.

Native Compatibility with J2EE Means More Rapid Development: Caché classes can easily be projected as EJBs, giving J2EE developers a simple way to connect to Caché’s high-performance database. When a Caché class is projected using bean-managed persistence, Caché automatically generates the method used by the EJB to access the Caché database. Because developers no longer have to hand code persistence methods, applications can be completed faster.


CACHÉ AND JALAPEÑO

Java developers who wish to create new database applications are faced with several problems today. Typically, they store their data in a standard relational database using SQL. With that approach, developers have to map their Java objects to relational structures and write tedious, and often complex, SQL queries to access that data – all of which can easily consume a high percentage of the total development time. Alternatively, a developer can make use of an object database, which often cannot support SQL and SQL-based reporting tools and may also require schema definitions.

Jalapeño (JAva LAnguage PErsistence with NO mapping) is an InterSystems technology that makes it easy for Java developers to persist their objects within the robust Caché object database using object access while simultaneously providing high-performance SQL access to the same data. Objects are stored in the database as true objects with properties, relationships, etc. (i.e., not by simply storing their serialized state), yet no object-relational mapping is required.

Using Jalapeño, the Java developer creates database classes the same way as any other POJO class, using the developer’s Java IDE of choice. The developer then indicates to Jalapeño which classes are database classes – usually by using a plug-in to the developer’s IDE provided by the Jalapeño Persistence Library. Jalapeño analyzes the classes, automatically creates a corresponding object (and SQL) database schema, and generates all of the runtime support for saving and retrieving such objects.

The developer’s POJO class is not modified, and the developer can continue to change it.

At run time, the application directly accesses properties and methods of the POJOs in the usual way. To save and retrieve database objects, the application uses the APIs of the ObjectManager class provided by Jalapeño. The ObjectManager class also provides methods that establish a connection to the database, support SQL queries, and provide transaction semantics such as start, commit, and rollback.

A simple class description, including a list of properties and their type, is not by itself rich enough to describe everything you might want in a database. At a minimum, it is necessary to also specify which property contains the object ID, and usually a developer would also like to specify indices to make queries more efficient. By adding standard Java annotations to their Java source files, developers can supply these and other database specifications.

Jalapeño also supports “schema evolution”, in which the developer can continue to modify the class, including adding new properties or changing property definitions, and the schema definition adapts without invalidating any of the already entered data. This results in a natural, iterative development process.

While Jalapeño works best when used with Caché, it can also export its database schema to a corresponding relational schema using standard DDL (Data Definition Language). Therefore, even though the application was built to use object access with Caché, it can also be deployed on a relational database. In this case, the Jalapeño ObjectManager APIs automatically use standard JDBC calls for database connectivity. When connected to the Caché object database, the higher-performance object-based protocol is used.

The Jalapeño library is implemented using standard Java and will run within any Java 1.5 (or higher) JVM or J2EE Application Server environment.

With Jalapeño, the Java developer can concentrate on the UI and business logic of the application, creating database classes the same way as other classes, and let Caché take care of the rest.

In the following example, a Customer object is retrieved, its phone number is changed with a “set” method, the database is updated, and the in-memory object is closed:

Customer = (Customer) objectManager.openById(Customer.class, customerId);
customer.setPhoneNumber("16176210600");
objectManager.update(customer, true);
objectManager.close();

 

THE CACHÉ ADVANTAGE

Fast, Natural Development with No Object-Relational Mapping: Jalapeño uses introspection of POJO classes to automatically create an object database schema. Data is stored as objects and a standard SQL representation of this data is also created automatically. No object-relational mapping is required, speeding development.

Easy POJO Persistence: Within an application, developers access their database classes just like any other class. Jalapeño generates all of the code to save and retrieve objects from the database using its runtime APIs.

SQL Access: All objects within the database are automatically accessible through SQL using Jalapeño’s JDBC API – even though the developer did not perform any object-relational mapping.

Database and Platform Independence: Caché is available on every major platform, and while Jalapeño works best when used with Caché, it can also export its database schema to a corresponding relational schema using standard DDL. Therefore, even though the application was built to use object access with Caché, it can also be deployed on a relational database.

CACHÉ AND .NET

Because of its open and flexible data access, Caché works seamlessly with .NET. There are many ways of connecting the two, including objects, SQL, XML, and SOAP. Developers can create applications with the technologies they prefer – all of them will benefit from Caché’s superior performance and scalability.

ADO.NET
ADO.NET is a new incarnation of ADO, optimized for use in the .NET framework. It is intended to make .NET applications “database independent”, and generally uses SQL to communicate with databases. Through its relational data access, Caché provides native support for ADO.NET. It also supports Microsoft’s ODBC.NET and the read-only SOAP connectivity that is built into ADO.NET.

Web Services
There are two ways of using Web services in .NET. One is to send XML documents over HTTP. The other is to use the SOAP protocol to simplify the exchange of XML documents. Because Caché can expose data both ways, it works seamlessly with .NET Web services.

Caché Managed Objects
Caché can automatically generate .NET assemblies (or C# source code) from Caché classes. A plug-in for Visual Studio lets developers who prefer that environment to easily access Caché objects.

THE CACHÉ ADVANTAGE

Speedy Data Serving: Web applications that use Caché as a data server benefit from the highperformance and massive scalability provided by Caché’s multidimensional data engine.

Faster .NET Development: Developers will be more productive when they work with their favorite tools in environments that are familiar to them. Providing both SQL and object data access, Caché supports a wide variety of common development technologies and tools.


CACHÉ AND XML

Just as HTML is an Internet-compatible markup language for displaying data in a browser, XML is a markup language for exchanging data between applications. The structure of XML data is hierarchical and multidimensional, making it a natural match for Caché's multidimensional data engine.

Exporting XML
All that is required to make a Caché class compatible with XML is to have it inherit from the %XMLAdaptor class that is included in Caché. This provides all the methods needed to:

  • Create either a DTD (Document Type Definition) or an XML Schema for the class. Caché will automatically generate DTDs and schemas, but developers who wish to customize the XML formatting of a class may do so.
  • Automatically format an object’s data as XML, according to the defined DTD or schema.

Importing XML
Caché comes with other classes that provide methods allowing developers to:

  • Import XML schemas and automatically create corresponding Caché classes.
  • Import the data in XML documents as instances (objects) of Caché classes, via a simple API.
  • Parse and validate XML documents via a built-in XML (SAX) parser.

CACHÉ AND WEB SERVICES

Web services enable the sharing of application functionality over the Internet, as well as within an organization or system. Web services have an interface described in WSDL (Web Service Definition Language), and they return an XML document formatted according to the SOAP protocol.

Caché enables any class method, any SQL-stored procedure, and any query to be automatically exposed as a Web service. Caché generates the WSDL descriptor for the service and, when the service is invoked, sends the appropriately formatted XML document. Caché also facilitates rapid development by automatically generating a Web page to test the service, without the need to construct a client application.

THE CACHÉ ADVANTAGE

Easy Connectivity to XML: Caché takes advantage of its capability for multiple inheritance to provide any Caché class a bi-directional interface to XML. The result: Caché classes can easily and quickly be turned into XML documents and schemas. Similarly, XML schemas and documents can be turned into Caché class definitions and objects.

Rapid Development of Faster XML Applications: Because Caché’s native multidimensional data structures are a good match to XML documents, there is no need for developers to manually code a “map” that translates between XML and the Caché database. And with less processing overhead, they run faster, too.

Instant Web Services: Any Caché method can be published as a Web service with just a few clicks of a mouse. Caché automatically generates the WSDL descriptor and the SOAP response when the service is invoked.

 

CACHÉ AND MULTIVALUE

Caché provides all the capabilities needed to develop and run MultiValue applications (sometimes referred to as Pick-based applications), including the MultiValue:

  • MVBasic language
  • File access
  • Query language
  • Data dictionary
  • “procs”
  • Command shell

This MultiValue functionality is provided as an integral part of Caché – not as a separate MultiValue implementation – and it utilizes the rich Caché multidimensional database engine, runtime functionality, and development technologies. This means that MultiValue users can take full advantage of all the Caché capabilities.

MultiValue File Access

MultiValue applications typically treat the database as a set of files accessed through Read and Write record operations and through MultiValue queries. In Caché, each MultiValue file is stored as a multidimensional “global” structure with each record being one global node. This feature relies on Caché’s ability to store multiple data elements per global node.

For example, a MultiValue file that stores invoices might have the following structure:

Invoice # 

Item ID

Customer 

Attribute 1

InvoiceDate

Attribute 2

Parts      

Attribute 3 (MultiValued)

Quantities 

Attribute 4 (MultiValued)

Prices 

Attribute 5 (MultiValued)

  …    

  …

Caché will internally represent this MultiValue file as the equivalent multidimensional global structure:


^Invoice(invoice #) =
Customer ^ InvoiceDate ^ PartNo1 ] PartNo2 ^ Quantity1 ] Quantity2 ^ Price1 ] Price2k

where “^” indicates the normal attribute delimiter (ASCII 254), and “]” indicates the subattribute delimiter (ASCII 253).

MultiValue files can be accessed by MultiValue programs through the normal READ/WRITE commands and MultiValue queries. They are also accessible by both MVBasic and other languages through all of the normal Caché mechanisms, including object access, direct multidimensional array access, and SQL.

MultiValue files may be indexed with a variety of index types (including bit-map indexes) and collation sequences.

MultiValue Query Language

The MultiValue Query Language provides both data selection and report formatting functionality for MultiValue files. The query language can be used in MVBasic, the command shell, and “procs”. Caché translates MultiValue queries into Caché SQL queries with additional code to support correlatives, report formatting, and various other features. Because these queries use Caché’s high-performance SQL engine, reliability is enhanced, execution is optimized, and a sophisticated set of indexing capabilities can be used. Of course, MultiValue developers can also use Caché SQL directly when desired.

MultiValue Data Dictionary

A MultiValue file may have a corresponding file description in the MultiValue Data Dictionary, which is directly editable through MVBasic code and through the traditional MultiValue “ED” editor. The MultiValue Query Language makes use of this dictionary.

A MultiValue file may also have a corresponding Caché class definition. A class definition is essential if the data is to be made available for object or SQL access (although it is not necessary to use the MultiValue Query Language). A class definition is also required if the file is indexed.

When importing older MultiValue applications, Caché class definitions can be automatically created from the MultiValue Dictionary. However, in most cases the resulting class will need to be edited to make the data more meaningful if SQL or object access is desired. A Studio wizard helps automate class creation from MV Dictionaries and provide further mappings at a later date. By default, these classes are read-only (so that the data can be read but not updated through objects and SQL) and edited separately from the MV Dictionary.

When creating a new MultiValue file, it is recommended to first create an Caché class inheriting from the MVAdaptor super-class, which will result in using a MultiValue compatible file format for data storage and will automatically create a file description in the MultiValue Data Dictionary. The file’s data will then be accessible and updateable through all of the Caché access paths, including object, SQL, and direct multidimensional global access. Thereafter, a developer would normally edit the class definition rather than the MultiValue Dictionary, as edits to the class are automatically reflected in the MultiValue Dictionary.

MultiValue and Objects

MVBasic has been extended to use objects in the same way as Basic does, except MVBasic uses the “->” syntax to represent object access rather than a period. Any class in the Class Dictionary can be used, regardless of the language used in the methods of the class.

Here are some examples of code in which “person” is an object reference:

person->Name = "Smith, John" 

// sets the person’s name

person->Home->City 

// references the
// person’s home city

person->Employer->Name

// brings the person’s employer object into
// memory and accesses the employer’s name

person->Save()

// saves the person to disk

                                                  

MultiValue Command Shell

The MultiValue command shell can be run from a terminal environment. In addition to the normal MultiValue command shell capabilities, Caché allows MVBasic commands to be directly executed in the command shell. For example, typing:

:; DIM A(34)
:; FOR I = 1 TO 34 ; A(I) = I; NEXT
:; FOR I = 1 TO 34 ; CRT A(I):” “: ; NEXT

yields the result:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34

 

THE CACHÉ ADVANTAGE

New Life for Old Applications: Caché makes it easy to modernize older MultiValue applications through browser interfaces, object access, robust SQL, and Web services. MultiValue applications can now live on an advanced database that is well accepted in demanding environments and constantly evolving.

Build New Applications Fast: Because MultiValue is implemented as a language and file access in Caché, all of the native Caché capabilities can be used to rapidly build new functionality. MultiValue programmers can begin to take advantage of object programming and easily interact with other applications while continuing to use the MVBasic language.

High-Performance and Scalability with Outstanding Reliability for MultiValue Users: Caché provides dramatically higher performance and scalability for MultiValue users. Plus, Caché is used in critical 24-hour environments, such as hospitals, with no tolerance for downtime. Caché provides sophisticated journaling, transaction processing, “bullet-proof database”, and fault-tolerant configurations.

Previous Page

Previous Page
Chapter 2

Table of Contents

Next Page
Chapter 4

Next Page