blob: 50bb9d11f0663a59747927f32cd2c8ed32d489c8 [file] [log] [blame]
eZ publish Enterprise Component: Database, Design
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Introduction
============
Purpose of the Database component
---------------------------------
The Database component provides an interface for:
- Database API abstraction
- SQL abstraction
It lets the user interact with different DBMSs using a common API. Such
differences between SQL dialects may include differences in OFFSET and LIMIT
clauses, left/right joins, temporary tables and strings quoting. These are also
handled transparently for the user.
Current implementation
----------------------
The current implementation mostly supports database API abstraction (built
on-top of PDO classes (see http://php.net/PDO); SQL abstraction is not
implemented yet.
Requirements
============
The component should provide simple but extensible API.
It must be possible for application to register support for other DBMSs.
Design
======
The component consists of the following main classes:
- ezcDbHandler
- ezcDbFactory
- ezcDbInstance
ezcDbHandler
---------------------
Provides the common interface for database operations, such as connecting,
running queries, etc.
This interface is derived by concrete *handlers*, e.g. MySQL handler or
PostgreSQL handler.
ezcDbFactory
------------
Implements a Factory design pattern.
It contains list of known handlers and is used to create instances of them.
It is possible to register user-specified handlers with the factory.
ezcDbInstance
-------------
Most applications need only one database connection. It is convenient for such
applications to create a connection once, and then make it globally accessible
and use it anywhere within the application.
Even if an application requires two or more database connections, it's handy
not to pass them to every method that needs them, but to access them easily
from any place.
To satisfy these requirements, the ezcDbInstance class is suggested. It's
capable of saving one or more database connections, with the ability to assign
them names (identifiers). These names can then be used to refer to the
connection.
How to use
==========
Usually the component is used in the following way:
- User creates an instance of a handler with ezcFactory class.
- (optionally) User saves the instance to singleton.
- He/she does misc. database operations on the instance.
A more sophisticated scenario includes defining a custom handler and
registering it with the factory.
If the user needs to work with several database connections simultaneously,
he/she creates several handler instances, then saves them to ezcDbInstance
giving them short name for sake of convenience.
Examples
========
Let's look at some examples to make everything clear.
Example 1: The simplest case
----------------------------
::
$dbparams = array(
'dbname' => 'circus',
'user' => 'monty',
'pass' => 'python' );
$db = ezcDbFactory::create( 'mysql', $dbparams );
$rslt = $db->query( 'SELECT * FROM tbl' );
In the example above we create an instance of MySQL handler and run a query on
it.
Example 2: Using singleton
--------------------------
::
$db = ezcDbFactory::create( 'mysql', $dbparams );
ezcDbInstance::set( $db );
unset( $db );
# ...
$db = ezcDbInstance::get();
$rslt = $db->query( 'SELECT * FROM tbl' );
In this case, we use ezcDbInstance to save the instance we have created. It
can be easily accessed from any place with just one one call to
ezcDbInstance::get(). The class ezcDbInstance behaves much like singleton in
this case.
Example 3: Multiple connections
-------------------------------
::
$db1 = ezcDbFactory::create( 'mysql', $dbparams1 );
$db2 = ezcDbFactory::create( 'mysql', $dbparams2 );
ezcDbInstance::set( $db1, 'db1' );
ezcDbInstance::set( $db2, 'db2' );
unset( $db1, $db2 );
# ...
$db1 = ezcDbInstance::get( 'db1' );
$db2 = ezcDbInstance::get( 'db2' );
Here we have two different MySQL connections. We save them to
ezcDbInstance, giving them names 'db1' and 'db2', accordingly. The
connections are then referred to in call to ezcDbInstance::get() by
these names.
Example 4: Custom handler
-------------------------
::
class MyOciDbHandler extends ezcDbHandler { ... }
# ...
ezcDbFactory::addImplementation( 'myoci', 'MyOciDbHandler' );
$db = ezcDbFactory::create( 'myoci', $dbparams );
$rslt = $db->query( 'SELECT count(*) AS cnt FROM user_tables' );
In this example we define our own handler for communicating with Oracle. The
handler is then registered with the factory by calling method
ezcDbFactory::addImplementation(). Then we can use the handler in the usual
way, as if it was a standard implementation.
See also
========
- For more information about PDO please visit the following page:
http://php.net/PDO
- See real examples (with errors handling) in test.php file bundled with
the Database package.