==============================
Architecture of Legacy Storage
==============================

This documents intends to provide a rough overview on the architecture of the
legacy storage and why it has been build like this. This document should be
read before any (structural) changes are made to the existing code.

Basic concept
=============

Almost every handler uses the same set of classes, which are build to enable
proper database abstraction and sane handling of the sometimes complex queries
and conversions. Let's take the relatively simple ``User\Handler`` as an
example. The following classes are defined::

    User/
    ├── Gateway
    │   └── EzcDatabase.php
    ├── Gateway.php
    ├── Handler.php
    └── Mapper.php

The ``Handler`` itself implements the handler interface, which is defines the
public interface to work with user data. All ``Handler`` implementations
aggregate a ``Gateway`` and a ``Mapper`` implementation.

Mapper
------

Mappers are used to transform data returned from the SQL queries into the value
objects used by the API. Those methods are mostly quite simple, but lengthy.
The usually expect a certain data format, which the gateway *must* follow. This
is usually not specified explicitely, because it is the natural array structure
returned by database functions.

Gateway
-------

The ``Gateway`` implementations are used to actually interact with a database.
The default implementation ``EzcDatabase`` uses the Zeta Components Database
component to abstract quries, so they can be executed against multiple
different Relation Database Management Systems (RDBMS).

The gateway layer has been introduced to make it possible to write optimized
queries for certain databases or modify queries, so that they work with a
database, which does not understand the common SQL.

It is also possible to make a gateway not use the Zeta Components Database
component at all, but entirely different methods for acccessing a database. For
example the Oracle-PDO extension has some stability problems, so it might be
sensible to use the native Oracle PHP extension here.

EzcDbHandler
^^^^^^^^^^^^

The ``EzcDatabase`` gateway implementations do not receive the connection
handle for the data directly, but a wrapped connection handle ``EzcDbHandler``,
which provides some additional convinience methods:

- ``aliasedColumn( \ezcQuerySelect $query, $columnName, $tableName = null )``
- ``quoteColumn( $columnName, $tableName = null )``
- ``quoteTable( $tableName )``
- ``getAutoIncrementValue( $table, $column )``
- ``getSequenceName( $table, $column )``

Especially the quote-methods are intended to be overloaded for databases which
have certain restrictions on table name length (Oracle).

The methods ``getAutoIncrementValue`` and ``getSequenceName`` make sure the
auto-increment handling works across multiple databases, which all implement
different variations of auto increment.

Search Handler
==============

The search handler itself contains some special features and concepts, which
are described in this section.

Searching involves filtering the content tree by the given recursive criterion
tree. The criterion filtered search result is then sorted based on a set of
given sort clauses.

For both, criteria and sort clauses, a handler structure has been implemented,
which implements handlers for each criterion or search clause. Additional
handlers for those can be added in the repository handler. The handlers itself
are fairly trivial and self explanatory.

Content-Type Handler
====================

In order to abstract updating of content types, the ``…\Legacy\Content\Type\Handler``
uses a dedicated handler ``…\Type\Update\Handler``. One of the existing
implementations of these abstractions realize type update in a synchronous
way, the other one relies on legacy eZ Publish functionality to realize an
asynchronous update.

The synchronous mechanism (``…\Type\Update\Handler\EzcDatabase``) makes also
use of the so-called Content-Updater, which takes care for updating existing
Content objects.

Storages and Converter
======================

There are basically 2 extension points for the Legacy Storage, which are
necessary in order to support custom field types:

- Converters (for fields and field definitions)
- Storages (for external storage of custom types)

All of these are available through the configuration of the
``…\Legacy\RepositoryHandler`` (as requested by eZ) and through public methods of
it, to be used for proper dependency injection. The corresponding interfaces /
abstract base classes are:

- ``…\Legacy\Content\FieldValue\Converter``
- ``eZ\Publish\SPI\FieldType\FieldStorage``



..
   Local Variables:
   mode: rst
   fill-column: 79
   End:
   vim: et syn=rst tw=79
