Object-Relational Layer

New approach

One of the key benefits of object technology is that it allows complex software systems to be developed by modeling the structure of the system with objects. These object models include both the entities (data) and the behavior (business logic) integrated into an interconnected web of components. This approach to building software as a set of black-box components helps us deal with the complexity of the system, and packages the logic and data in way that lets us maintain and understand the software over time.

In practice, the bulk of these object models are developed by companies building business software. A common characteristic of these systems is that these business objects must be made persistent - they must outlive any single business process that might manipulate them. One approach is to store these objects in an object database. While this solution is the most natural, i. e. objects in the programming environment are directly stored in the same form in an object database, all the same most organizations do not currently use an object database. In fact, the majority of information in today's enterprises is stored in relational databases. Most of today's organizations require that objects be stored in these existing databases. Mapping rich semantic world of objects into non-object databases is surprising difficult to implement adequately, especially when inheritance and complex relationships are involved.

Object-relational layer entitled Persistence Smith is a set of software tools and runtime services that allows developers to build enterprise-level object models and then automatically generate the bindings to the proper database. Using techniques pioneered by object databases, and standards created by OMG, ODMG and ANSI Persistence Smith provides an object-database interface to standard RDBMS. Using this interface programmers can develop using objects and handle the complexity of moving objects into and out of the database. Persistence Smith seamlessly solves the object-to-database mapping problem.

Persistent classes

General C++ objects are transient entities. They are created, manipulated, and destroyed within an execution scope of an application program. Persistent objects survive beyond the execution of an application. Their attribute data is permanently stored in some repository so that the object can be instantiated, that is, reconstructed for each execution of a using application. The services which maps between the virtual storage representation and the disk residence of such objects are referred to as the persistent services.

ODMG Object Model

The data models in object oriented languages are extremely rich, in that they support hierarchies of objects, objects containing other objects, objects referencing other objects, and non-objects such as arrays (themselves containing arbitrary data types). Traditional databases do not allow anywhere near this flexibility, but persistent systems should support it.

Persistence Smith implements the key concepts of the ODMG Object Model. It specifies the kinds of semantics which determines the basic modeling primitives, states of objects, their behavior, how objects can be related to each other and how they can be named and identified. An application developer uses the semantic constructions to build the object model for the application. The application's object model specifies particular business types and the operations and properties of each of these types. The application's object model is the logical schema mapped to the relational database.

Database functionality of C++

Persistence Smith adds database functionality to C++. It brings much more than persistent storage of programming language objects. Persistence Smith extends the semantics of the C++ to provide full-featured database programming capability, while retaining native language compatibility. A major benefit of this approach is the unification of the application and database development into a seamless data model and language environment. As a result, applications require less code, use more natural data modeling. Also code is easier to maintain. Object developers can write complete database applications with a modest amount of additional effort.

The C++ binding provides language-transparent extensions to support object creation, naming, manipulation and deletion. The C++ binding allows persistence-capable classes to be created by inheritance. Exception handling and transaction management are also included.

Object-oriented paradigm

Elements of the object-oriented paradigm are encapsulation, inheritance and polymorphism. Encapsulation is provided by packaging of data and methods into a class. Inheritance represents a relationship between two objects, such that a child object embodies all the attributes and methods of a parent object. Persistant Smith falls into vertical partitioning category of so called class-based object engines. This means that each non-inheritied attributes of a class form a tuple and objects derived from inheritance are spread over several tuples in their lineage.

Polymorphism is a way to treat objects of different classes in a generic way, so that you do not need to know the type of the object you are interacting with. The cost value of all the objects, derived from CAsset class, whether of the CEquipment, the CInventory, the CCash or some other class that represents enterprise's available capital, can be obtained exactly the same way, even though they are calculated differently within the class.

Other examples of object-oriented semantics preserved by use of Persistence Smith include aggregation, association and strong data typing. Aggregation represents an obligatory one-to-one relationship between objects. With association one object references another object or objects. Inheritance, aggregation and association result in graphs of connected objects. These complex relationships is preserved when mapped into a relational domain.

Relational databases preserve no form of type checking over a tuple. A tuple is simply a group of columns, each holding a particular piece of data. Each piece of data has an associated data type such as a character or an integer, but the tuple as a whole maintains no consistent form that can be re-used through the enterprise. Persistence Smith provides this additional type preservation that readily allows existing relational data to be incorporated into new applications.

Persistence services

The persistence services allow an object-oriented application to be independent of the underlying data store. Adaptation is done through the addition of alternative mapping definitions. Persistence Smith does not impose a particular object architecture to enable persistence. Developers are free to choose an architecture that is appropriate for their applications, which is independent of the storage systems used.

Object i/o is one of the simplest forms of persistence. When an object is instantiated in virtual storage, a reference to the object essentially becomes a pointer, which the persistence service maps to a virtual storage address. Access through the pointer is extremely fast. This mechanism is especially valuable for compound objects, where an object references another ones. The pointers make navigation between objects fast and easy.

When objects are made persistent the pointers become meaningless. Chances are very good that the next time the objects are instantiated in virtual storage, different pointers would be established. The relationship between objects established by these pointers, however, must be maintained. For persistence these pointers must be transformed to a representation (an identifier) that allows reconstruction of the relationship the next time the objects are instantiated in virtual storage.

Persistence Smith uses popular relational databases to organize the underlying repository. These datastore technologies include heavy MS SQLServer, Sybase, SQLAnywhere, Oracle, Gupta SQLBase engines and lightweight MS Access. Most of the persistence services are implemented via use of object-relational layer, while several core ones, such as storage, indexing, integrity, query optimization, recovery and security rely on the RDBMS. In that case the Persistence Smith transparently transforms requests from application as a client to database server dispatching them through layer.

Persistence Smith manages inheritance, polymorphism, aggregation, object identity, i/o, instance lifecycle, dereference by demand, collections, complex relationships, object queries, concurrency, threads, transactions. Mapping of database types to object ones including large numbers, currency, date, time, text, and blobs is persistence service too. Object-relational layer incorporated directly into the client application and allows client to use multiple RDBMSs simultaneously.

Workspace architecture

Workspace is a logical entity that ties together the resources involved in a transaction. It is a means of managing objects, transactions, multiple data sources, caching and garbage collection. In essence, Workspace is an in-memory container and manager of all objects and relationships created and fetched during the course of transaction and bound to a common process regardless of the database server they reside in. Workspace is an implicit part of a thread. Each thread can have its own workspace, and the application can create as many workspaces as it needs and swap them in and out if necessary. Being linked to unit of work, Workspace eliminates the need to write complex undo and clean up code by ensuring that all objects and resources it manages are released on a transaction checkpoint or when a process terminates.

This technique provides a unified view of all enterprise data as a singular object graph. Workspace functions as a sophisticated object cache that helps manage object references and keep track of all objects read from the database and ensures that any particular object is read only once during the course of a transaction. Persistence Smith automatically performs the synchronization, context switching and transaction completion logic making it easy to write applications that are secured by transactions.

Persistence Smith has trace options for debug purposes. There is a spy upon object states, data driver events, cache of object graph, threads and transactions.

Object queries

Application developers have the ability to execute both simple and complex queries to find their objects. Queries is database-independent and object-centric, they are issued directly to the object model instead of the physical database. Application obtains result set of objects imposing search and sort predicates upon the application domain. Single-value results are received by means of attribute aggregation with optional searching. This is one of the object-relational mapping features that isolates applications from the physical storage schema of the database.

Detailed technical overview

Click here to inspect detailed technical overview of object-relational layer Persistence Smith.