Caché

You’ll make breakthroughs
in
data management 
and rapid development

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

By writing as much code as possible in these scripting languages, programmers can develop applications faster, and those applications will run significantly faster with greater scalability. Plus, code written in Caché ObjectScript, Basic, or MVBasic requires no changes to switch hardware or operating systems. Caché automatically handles all differences in operating systems and hardware.

Scripting-Languages-chart

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 percent 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

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.

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.

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

Routines 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

56501510_11_smBasic 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é Object Model 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.

2People-on-cubes

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.

Caché also provides Caché eXTreme technology for C++. This is a “light binding” that allows C++ objects to inserted directly into Caché’s multidimensional database, enabling extremely high performance.

Java

100032-199Java is a popular object-oriented programming language, but because of its “write once, deploy anywhere” flexibility, it does not specify how data is written to, or read from, a database. When data needs to be persisted, Java developers must choose and implement data access methods.

Caché provides several ways for Java applications to access the Caché database:

  • JDBC provides high-performance SQL access using a completely Java-based (Type 4) driver.
  • Any Caché class can be projected as a Java class so properties and methods can be accessed as Java objects.
  • InterSystems Jalapeño™ technology creates Caché classes from Java classes. Caché automatically provides methods to store and retrieve objects from the database without touching the developer’s classes.
  • Caché eXTreme for Java exposes Caché data via the JNI (Java Native Interface)
  • Java Persistent API (JPA) is enabled through both Hibernate and EclipseLink implementations to provide standard Java EE persistence support.

Caché eXTreme for Java

Caché eXTreme for Java exposes Caché’s enterprise and high-performance features to Java via the JNI (Java Native Interface). It enables “in-process” communication between Java and Caché‚ thereby providing extremely low latency data storage and retrieval.

Caché eXTreme for Java gives developers a Java API (Application Programming Interface) that provides in-process communication for:

  • Storing and retrieving relational data via JDBC (JDBC over JNI)
  • Storing and retrieving Java objects
  • Storing and retrieving multidimensional data

The Globals API option provides Java developers with direct access to Caché’s efficient multidimensional data structures.

eXTremeJava2_sm

The Caché Advantage

Very High-Performance Persistence: Caché eXTreme for Java speeds up database I/O for Java applications. It will be especially beneficial when building or enhancing Java applications that deal with streaming data‚ very high volumes of data‚ or rapidly changing data.

Multiple Modes of Data Access: Caché eXTreme for Java provides speedy “in-process” communication between Java and Caché via JDBC, object access, or direct multidimensional access.

Short Learning Curve: Caché eXTreme for Java uses Java standards to provide database access, so Java developers can work mostly within a Java environment. Typically, a Java developer with a year of experience can be productive in just a few days when using Caché eXTreme.

Enabling persistence for Java-based CEP applications

Most CEP (Complex Event Processing) applications cannot use persistent databases because the latency introduced by storing and retrieving information to/from disk is too great. Instead‚ they typically use in-memory databases‚ and run the risk of losing data or transactions. But by using Caché eXTreme for Java‚ Java-based CEP applications can persist data without sacrificing performance.

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 high-performance 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

rainbow-fpo_smWeb services enable the sharing of application functionality over a network, either worldwide via the Internet, or within an organization or system. The body of a Web service is an XML document, which is contained in an “envelope” usually formatted according to the SOAP (Simple Object Access Protocol) standard. Web services have an interface described in WSDL (Web Service Definition Language).

Any existing Caché class can be marked as a Web service simply by making it inherit from the appropriate system-level classes that come with Caché. There is also a Web Services Wizard for generating new Web services with just a few clicks of a mouse. In both cases, when the Web service is compiled, Caché generates the WSDL descriptor for the service, as well as constructing and formatting the needed “envelope”. 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.

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.

Secure Web Services: Caché provides features that enable you to easily secure the integrity and confidentiality of Web services. Its use of the WS-policy framework greatly simplifies the task of securing Web services

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.

Securing Web Services

Web services represent “data in motion” and may come from “unknown” sources. Therefore, they require special security measures.

Caché supports the use of SSL and TLS to secure connections. As for the Web services themselves, information provided with the “envelope” of the service should enable the recipient to verify who the Web service is from, that it has not been tampered with en route, and to decrypt the contents.

Caché implements many features outlined in the WS-Security specifications published by the OASIS-Open standards organization:

  • WS-Security Header
    • Provides for message integrity

The security header is added to the header of a SOAP message. It contains all the security-related information of the message, including tokens (Username, Binary Security, Timestamp), signature elements, and encrypted key elements.

  • XML Signature List: Provides for message integrity

Enables you to verify who a Web service comes from

  • WS-Security Token Support: Username Tokens

Enables you to verify identity to Web Services that require authentication

  • Binary Security Tokens

Used as references for signature and encrypted key elements

  • XML Encryption: Provides for message confidentiality

Configuring Security for Web services

To make it easier to configure and manage Web services security, Caché uses the WS-Policy framework outlined by the W3C (World Wide Web Consortium). A wizard is provided that helps application developers generate a WS-Policy efficiently. It includes various options to select the details of the policy.

SOAP Log

It is often useful to log or trace SOAP messages so that you can “see” what was sent over the wire. The Caché SOAP log can (if you wish) capture inbound and outbound messages, as well as security information.

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

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.

  • Query language

The Caché MultiValue Query Language (CMQL) provides both data selection and report formatting functionality for MultiValue files. Because these queries use Caché’s very high-performance SQL engine, reliability is enhanced, execution is optimized, and a sophisticated set of indexing capabilities can be used.

  • Data dictionary (7- and 10-line structures)

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. 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.

  • Procs, Paragraphs, and Phrase
  • 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.

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.

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.

Migrating Applications to Caché

Caché includes features and utilities that can help you migrate existing applications from a number of different technologies to Caché. It allows you to keep your existing data and leverage your existing code, while gaining the performance, scalability, and advanced capabilities of Caché.

Migrating from relational technologies

Caché has specialized implementation of SQL to help you port your applications from:

  • Microsoft SQL Server and Sybase Adaptive Server

Caché TSQL is an implementation of Transact-SQL. It supports many of the features of both the Microsoft and Sybase implementations.

  • Informix

Caché ISQL is an implementation of Informix ISQL It supports many Informix ISQL features

Caché includes system-level classes for importing and compiling DDL, DML, and stored procedures. There is a Data Migration Wizard for importing existing data into Caché.

Migrating from MultiValue technologies

Caché supports migrations from all the popular MultiValue environments, including Universe, Unidata, JBASE, D3, and Reality.

  • Caché’s multidimensional arrays (globals) are a superset of MultiValue files, so it is easy to migrate existing data and schema from MultiValue technology to Caché.
  • Caché MVBasic is a highly optimized implementation of the Basic programming language used in MultiValue applications. Dialect differences are accommodated by emulation switches – thus minimizing the code changes required when migrating.
  • Caché offers CMQL, a MultiValue query language implemented on our highly optimized SQL query engine

The Caché Advantage

Easier Migrations: Utilities and Wizards make migrating from relational or MultiValue technologies as easy as possible.

Higher Performance: Caché- based applications have been shown to run SQL up to five times faster than applications based on relational technology.

More Options for Future Development: Once migration is complete, you can continue to enhance your applications using the full array of Caché capabilities, including InterSystems Zen technology, object-oriented development, iKnow technology, and more.

Enhanced Scalability, Security, and Resiliency: Caché-based applications can take advantage of capabilities such as Enterprise Cache Protocol (ECP), the Caché security model, and mirroring