This software is OSI Certified Open Source Software. OSI Certified is a certification mark of the Open Source Initiative.
The license (Mozilla version 1.0) can be read at the MMBase site. See http://www.mmbase.org/license
Abstract
The Storage layer is a set of classes that provide a transparent interface for MMBase to store and retrieve data.
Table of Contents
The Storage layer is a set of classes that provide a transparent interface for MMBase to store and retrieve data.
The interface was created after the old model (the MMJDBC2NodeInterface) proved unsatisfactory. The storage layer is set up to discourage direct reference of database-specific code.
The layer is meant to be device independent. A storage will most often refer to a database. However, the outer interface is set up in such a way that it will be possible to provide alternative 'storages', such as storing data in files (i.e. xml), in memory, or across servers.
Aside from transparency, the storage layer allows for the use of transactions. While not every storage implementation will actually implement transactions, the setup for the storage layer allows for it.
The goal of the storage project was to create a layer of classes that allowed device independent access to the storage by the MMBase core and support for transactions at the storage level, while making it relatively easy to add solutions (by overriding classes) for storage-specific issues.
The first (beta) version of the storage layer was released in the
1.6 release of MMBase, and contained of a
Storage
and a
Transaction
interface. The
Storage
interface allowed for the
implementation of storage-specific elements (such as specific
methods for handling of Blobs, database access, etc). The
Transaction
interface was intended
for transaction tracking, committing and rollback. Eventually,
this approach did not turn out as useful as we hoped, as the
implementations of these interfaces were too dependent of each
other. In addition, backward compatibility was rather hard to
achieve.
The current setup, firstly released in 1.7, differs considerably
from that first version. We now have a
StorageManager
interface, which
grants access to the storage for one user and which grants the
ability to start a transaction, and a
StorageManagerFactory
class, which provides
StorageManager instances, and gives access to the global storage
configuration parameters.
The storage classes will be included in the MMBase core, so no additional software need be installed.
You will, however, need to tell the MMBase system that you intend to use the (new) storage layer. In the default configuration, the system already uses the new storage layer. When upgrading older systems, you need to make changes as outlined below.
The following steps need to be taken:
MMBase by default uses the old (pre-1.7) database abstraction
classes, which implement the
JDBC2NodeInterface
. To force
MMBase to use the new storage layer, you need to add a
property specifying the storagefactory classname to the
mmbaseroot.xml configuration file (found in the modules
configuration directory) :
<property name="storagemanagerfactory">org.mmbase.storage.implementation.database.DatabaseStorageManagerFactory</property>This prompts MMBase to call the
JDBC2NodeWrapper
class, a special
implementation of the JDBC2NodeInterface that wraps the storage
layer.
We now need to set up how the storage layer accesses the database. There are two ways of doing this.
The first, and obviously easiest way for older systems, is to use the JDBC module. If you use this method, you do not need to change anything in your setup. See the configuration document for how to configure the JDBC module.
The second method is to leave database access and maintenance of such elements as connection pools to the application server.
This is a more elegant way of accessing the database, but requires some knowledge of how to set up an application server's data-sources (a class that provides a database connection). Information on setting up data sources can be found in the documentation of your application server. See the configuration document for an example.
After setting up the data source, you need to specify a JNDI pointer to it. This pointer is an identifier equal to one of the 'location' identifiers specified for the data source. We recommend using the 'ejb-location' identifier ('dbc/HsqldbDS' in the example), as that will provide connection pooling, which speeds up the storage layer.
The data source is once again a property set in the mmbaseroot.xml file:
<property name="datasource">jdbc/HsqldbDS</property>
If you use this method, you need to turn off the JDBC Module (by setting it's status to inactive).
The storage layer will now be able to connect tot the database.
MMBase needs some additional configuration data to deal with the database connection. Most databases have some peculiarities, but by specifying the right parameters you can work around this. You can set up your own resource, or use the set of resources delivered with MMBase.
MMBase provides a mechanism to automatically determine what configuration to use, based on information obtained from the data source. As such, you generally only need to specify what configuration to use if you have your supply own configuration file, or if MMBase, for some reason, fails to correctly determine what database you have.
To explicitly set the configuration resource to use, specify a pathname to it in the 'database' property in the mmbaseroot.xml file:
<property name="database">/org/mmbase/storage/implementation/database/resources/hsqldb.xml</property>
The path is a classpath to the resource (the resource needs to be present in the MMBase classpath). If the resource is a .xml file located in the org.mmbase.storage.implementation.database.resources package, you can use shortcut notation as follows :
<property name="database">hsqldb</property>
The storage will automatically expand the name to its correct resource path.
Once the above steps are run, you should now be able to connect to your database using the storage layer.
Changes in configuration may mean database act differently under the new Storage Layer. Specifically, the new PostgreSQL configuration now stores blob files on disk, rather than in the database. If you have been using PostgreSQL with the old support classes, you will either need to provide an alternative postgresql resource, or run a conversion in which you move data from the database to the file system.
The Storage layer has been set up taking various database servers into account. While it is not possible to capture all freaky differences between servers, a lot of it can be configured using the database resource files. You can create your own file to override specific behavior for your database. The resources delivered by MMBase have been set up to provide optimal performance. If you are upgrading, you may need to change resources to deal with specific changes introduced in 1.7. See the configuration document for details on the parameters you can change.
How to on how to convert between databases, and field-types.
In MMBase 1.7, access to the database is still done through the JDBC2NodeInterface. This section describes how MMBase will access the storage layer in future releases of MMBase.
In order to get access to a storage (for querying, updating objects, or obtaining configuration data), you first need to obtain the factory. You can obtain this by requesting it from a static method in the StorageManagerFactory class (an abstract class in the org.mmbase.storage package), by passing the MMBase module as a reference. This will look like:
StorageManagerFactory storageFactory = StorageManagerFactory.getInstance(this);
The code can then obtain or change configuration data, or obtain access to the storage by requesting a StorageManager object:
StorageManager storage = storageFactory.getStorageManager();
The StorageManager now grants access to the actual storage. You can call methods on the instance that query data, add, update, or remove methods, or which change storage collections (nodemanagers or builders). You may also start a Transaction allowing you to rollback changes when errors occur (provided the implementation allows for it). The actual methods available to you will be detailed in the next chapters.
The StorageManager instance should be treated as granting access for one session only - do not keep it as a static or otherwise longterm member of a class. An instance that starts a transaction may get invalidated if the transaction takes too long.
The StorageManagerFactory also allows you to retrieve (or change) options and properties (attributes) of a layer. Possible options include database schemes (which allow you to tweak SQL statements for performance), setting prohibited field names, turning storage-altering commands on or off, or specifying directories for storing data such as binary files. There are also attributes for plugging in filters in the retrieval and setting of strings to and from the database.
These options may be specific for certain implementations and not available in all cases.
This is part of the MMBase documentation.
For questions and remarks about this documentation mail to: [email protected]