InterJinn

Development Framework For PHP

interJinn
Class JinnDatabaseManager

public class JinnDatabaseManager
extends JinnBaseService

Provides an interface for working with an SQL database. The default service interacts with a MySQL database; however, another replacement database service exists which uses the PEAR:DB system for accessing different kinds of databases. Database connections must be configured via $GLOBALS['interJinn']['databases']. By default this service works in harmony with instances of JinnDBConnection. The following is an example configuration:

$GLOBALS['interJinn']['databases'] = array
(
   
'myProject' => array
    (
       
'type'     => 'mysql',
       
'host'     => '192.168.1.3',
       
'socket'   => '/var/run/mysqld/mysqld.sock',
       
'user'     => 'php',
       
'password' => 'sECrEt',
       
'db'       => 'secret_mission'
   
),

   
'freakyForum' => array
    (
       
'type'     => 'microsoftAccess',
       
'host'     => '',
       
'user'     => 'php_remote',
       
'password' => 'nOtSoSEcREt',
       
'db'       => 'freaky_forum'
   
),

   
'forum' => 'newsFeed',
   
'default'   => 'myProject',
);

The above structure can be described as any number of database connection configurations for which the key is the registered name. Additionally, any keys whose value is a string describes an alias to the database configuration with that key. In this way database connections are named and can be modified without having to change code anywhere in the application. it is important to note that a default entry must be defined. This facilitates database connection requests without the need for a name-- a useful feature for services that make use of the database.

Following is a detailed list of configuration fields supported by this database service (replacement services may differ in the fields available depending on their connection criteria):

type The type of database connection being requested. This is used to dispatch the connection request to the appropriate handler.
host The IP or domain name of the machine hosting the database server.
port The port on which a connection to the database server should be made. If omitted then the default MySQL database port is assumed.
user The username of the account with which to connect to the database server.
password The password associated with the username of the account with which to connect to the database server.
database The name of the database to which queries will be made.

Following is an example of retrieving a database connection, performing a query, and processing the results:
//
// Presumes we are in a class that at some level extends
// JinnBaseClass.
//
$sDb = &$this->getServiceRef'dbManager' );
$db = &$sDb->getConnectionRef();

$qString =
   
"SELECT "
   
."   name, "
   
."   accessLevel "
   
."FROM "
   
."   users "
   
."WHERE "
   
."   id = ".$db->quote$userId )." ";

if( 
$db->query$qString ) )
{
    while( 
$db->nextRow() )
    {
        echo 
$db->getField'name' )
            .
' - '
           
.$db->getField'accessLevel' )
            .
'<br />';
    }
}

$db->free();


Notes
Warning:
Don't forget to define a default entry in your configuration, it can be the key for a literal configuration, or an alias for an existing named configuration.  

Direct Known Subclasses
PearDbManager  

Method Summary
public JinnDatabaseManager( )

Constructor.
public ___jinnConstruct( )

Constructor.
private checkConnectionParams( array   & $params )

Traverses the connection configuration and trims each value.
public & connectionFailureHandler( object   & $connection , object   & $connection )

Specifically added so that the service can be overridden with minimal effort to provide handling for when a conneciton could not be properly retrieved.
private array & dispatchConnectionRequest( string   $type , array   $params )

Attempts to retrieve a connection of the given database type and returns it.
private freeConnection( object   $connection )

Called by a connection object to have the database manager make it available for re-use in the pool of connections.
public object & getConnection( mixed   $params )

Requests a database connection object with the given parameter characteristics.
public object & getConnectionRef( mixed   $params )

Requests a reference to a database connection object with the given parameter characteristics.
private integer getIncrementalId( )

Used to enumerate pooled connections resources.
private string getParamString( array   $params )

Creates a string based on the given connection configuration.
public resource & getResource( mixed   $params )

Used to retrieve a MySQL connection resource.
private array lookupDB( string   $name =default )

Attempts to find the database configuration having the requested name.

Methods Inherited from JinnBaseClassReal
JinnBaseClassReal , ___jinnConstruct , __destruct , applyCallbackRecursively , checkpoint , cleanPath , createClone , error , extractPairs , flattenPath , getBacktrace , getCharset , getCodeRoot , getCompileVar , getCompileVars , getCoreRoot , getFilename , getHttpCookieVar , getHttpCookieVars , getHttpEnvVar , getHttpEnvVars , getHttpGetOrPostVar , getHttpGetVar , getHttpGetVars , getHttpLinkVar , getHttpLinkVars , getHttpPostFile , getHttpPostFiles , getHttpPostOrGetVar , getHttpPostVar , getHttpPostVars , getHttpServerVar , getHttpServerVars , getImageBase , getInterJinnVar , getInterJinnVars , getLanguage , getLanguageDefault , getLibrary , getLibraryRef , getLoadInfo , getPageBase , getPageRoot , getPath , getPathPrefixType , getPrintData , getPrintFlat , getRunMode , getRunUid , getService , getServiceRef , getShellArg , getShellArgc , getShellArgv , getTime , getUniqueId , getVersion , getWebProfilingCategoryColour , getWebProfilingDataColour , getWebProfilingDefaultColour , halt , haltWithProfile , hashAppend , hashKeyDelete , hashKeyExists , hashKeyGet , hashKeyIsSet , hashKeySet , hashPathDelete , hashPathDeleteData , hashPathExists , hashPathGet , hashPathGetData , hashPathIsSet , hashPathSet , hashPathSetData , includeResource , isProfiling , libraryExists , localizeImage , localizePage , localizePath , logData , logFlat , makeRelativePath , markup , multilingualize , multilingualizeRef , normalizeArray , notice , overrideWarning , printData , printFlat , purgeOutputBuffers , redirect , refresh , serviceExists , setInterJinnVar , stripSlashes , stripSlashes_primitive , unwrapIfNecessary , unwrapObject , warning , wrapIfNecessary , wrapObject , xpathExists , xpathGet , xpathGetData , xpathIsSet  

Methods Inherited from JinnBaseClass
JinnBaseClass , ___jinnConstruct  

Methods Inherited from JinnBaseService
JinnBaseService , ___jinnConstruct , allowCopies , postLoadExecute  

Method Details
JinnDatabaseManager

public JinnDatabaseManager ( )

Constructor. Initializes data structures used by this service.

Source Code
function JinnDatabaseManager()
{
   
$this->___jinnConstruct();
}

___jinnConstruct

public ___jinnConstruct ( )

Constructor. Initializes data structures used by this service.

Source Code
function ___jinnConstruct()
{
   
parent::___jinnConstruct();

   
//
    // The $connectionPool is a 2 level pooling hash. The first level
    // links a set of connection parameters to an array of all connections
    // using those parameters. The second level contains the actual master
    // connection objects.
    //
   
$this->connectionPool = array();

   
//
    // The $connectionLookup is a mapping of unique IDs as generated by
    // this class to associated resources. This makes it quick to free a
    // connection since we can just lookup the master object.
    //
   
$this->connectionLookup = array();

   
//
    // Set default parameters to empty. Default should preferably be set
    // up in the project configuration file.
    //
   
$this->defaultParams $this->lookupDB();

    if( 
$this->defaultParams === null )
    {
       
$this->defaultParams = array();
    }

    if( 
$this->isProfiling() )
    {
       
//
        // Add query time to accumulator.
        //
       
$accPool = &$this->getServiceRef'accManager' );

       
$queryAcc =
            &
$accPool->getRef(
               
'debug_queryTimes'true );

       
$queryAcc->append
       
(
           
'<div class="title">'
           
.'Query Times'
           
.'</div>'."\n"
       
);

       
$totalQueryAcc =
            &
$accPool->getRef(
               
'debug_totalQueryTime'true );

       
$totalQueryAcc->append
       
(
           
'<div class="title">'
           
.'Total Query Time'
           
.'</div>'
           
.'<div class="data">'
           
.'<span class="label">'
           
.'Total Queries: '
           
.'</span>'
           
.'<span class="timeSubTotal">'
           
.'[ 0 ]'
           
.'</span>'
           
.'<span class="label">'
           
.'Total Time: '
           
.'</span>'
           
.'<span class="timeSubTotal">'
           
.'[ 0.00000000 ]'
           
.'</span>'
           
.'<span class="label">'
           
.'Average Time: '
           
.'</span>'
           
.'<span class="timeSubTotal">'
           
.'[ 0.00000000 ]'
           
.'</span>'
           
.'</div>'
       
);
    }
}

checkConnectionParams

private checkConnectionParams
(
     array      & $params
)


Parameters:
$params - A connection configuration array.

Traverses the connection configuration and trims each value. I think once upon a time this did more but eventually was pared down to what remains *lol*.

Source Code
function checkConnectionParams( &$params )
{
    foreach( 
$params as $key => $value )
    {
       
$params[$key] = trim$value );
    }
}

connectionFailureHandler

public & connectionFailureHandler
(
     object      & $connection ,
     object      & $connection
)


Parameters:
$connection - The connection object that was returned for which the connection failed.
$connection - A replacement connection object.

Since:
0.9.3

Specifically added so that the service can be overridden with minimal effort to provide handling for when a conneciton could not be properly retrieved. For instance the default behaviour generates a warning and returns a connection object without a real connection to the database server. This can be overriden to abort the script thus preventing further problem. The return value may be used to try and re-attempt the connection request and return the new object if valid. If not, and the script aborts, then the original connectio should be returned.

Source Code
function &connectionFailureHandler( &$connection )
{
    return 
$connection;
}

dispatchConnectionRequest

private array & dispatchConnectionRequest
(
     string      $type ,
     array      $params
)


Parameters:
$type - The type of database connection to retrieve.
$params - The configuration array describing the database connection.

Returns:
An appropriate database connection for the given type. On failure null is returned.

Attempts to retrieve a connection of the given database type and returns it. If the type is not recognized then it assumes MySQL.

Source Code
function &dispatchConnectionRequest$type$params )
{
   
$newConnection null;

    if( 
$type === 'microsoftAccess' )
    {
       
$sMicrosoftAccess = &$this->getServiceRef'dbMicrosoftAccess' );
       
$newConnection = &$sMicrosoftAccess->getConnectionRef$params );
    }
    else
    {
       
$newConnection = new JinnDBConnection$params );
    }

    return 
$newConnection;
}

freeConnection

private freeConnection
(
     object      $connection
)


Parameters:
$connection - An appropriate database connection object.

Called by a connection object to have the database manager make it available for re-use in the pool of connections.

Source Code
function freeConnection$connection )
{
   
$conn = &$this->unwrapObject$connection );

   
$poolId $conn->friendlyGetPoolId();

    if( isset( 
$this->connectionLookup[$poolId] ) )
    {
       
$conn = &$this->connectionLookup[$poolId];
       
$conn->friendlySetFree();
    }
}

getConnection

public object & getConnection
(
     mixed      $params
)


Parameters:
$params - The name of a database or an explicity connection configuration structure. If the value is null then the default database is presumed.

Returns:
A database connection object upon which queries can be made and retrieved.

Requests a database connection object with the given parameter characteristics. This function uses pooling techniques so that the first unused connection is returned or a completely new connection is created if no pooled connections are available.

Source Code
function &getConnection$params=null )
{
   
$connection = &$this->getConnectionRef$params );

    if( 
$connection === null )
    {
        return 
$connection;
    }

   
$wrapped = &$this->wrapObject$connection );

    return 
$wrapped;
}

getConnectionRef

public object & getConnectionRef
(
     mixed      $params
)


Parameters:
$params - The name of a database or an explicity connection configuration structure. If the value is null then the default database is presumed.

Returns:
A database connection object upon which queries can be made and retrieved.

Requests a reference to a database connection object with the given parameter characteristics. This function uses pooling techniques so that the first unused connection is returned or a completely new connection is created if no pooled connections are available.

Source Code
function &getConnectionRef$requestParams=null )
{
   
$params $requestParams;

    if( 
is_array$requestParams )
        ||
        (string)
$requestParams === '' )
    {
       
$requestParams 'default';
    }

    if( !
is_array$params ) )
    {
        if( (
$params $this->lookupDB''.$params )) === null )
        {
           
$newObject null;
            return 
$newObject;
        }
    }

    if( !
is_array$params ) )
    {
       
$params $this->lookupDB();
    }

   
$this->checkConnectionParams$params );

   
$paramString $this->getParamString$params );

   
//
    // Check if a connection already exists.
    //
   
if( isset( $this->connectionPool[$paramString] ) )
    {
       
//
        // One or more connections exist, so try and find an free
        // connection and return it.
        //
       
foreach( $this->connectionPool[$paramString] as $poolId => $foo )
        {
           
$aConnection = &$this->connectionPool[$paramString][$poolId];

            if( 
$aConnection->friendlyIsFree() )
            {
               
//
                // Mark the connection as in use.
                //
               
$aConnection->friendlySetUsed();

               
//
                // Copy the object, this is what we actually return.
                //
               
$newObject $aConnection;

               
$newObject->jinnId $requestParams;
                if( 
is_array$requestParams ) )
                {
                   
$newObject->jinnId null;
                }

                return 
$newObject;
            }
        }
    }

   
//
    // If we are here, then no connections were in the pool to meet
    // our needs and we must generate a new connection.
    //
   
$type null;
    if( 
is_array$params ) && isset( $params['type'] ) )
    {
       
$type $params['type'];
    }

   
$newConnection = &$this->dispatchConnectionRequest$type$params );

    if( 
$newConnection
       
&&
       
$newConnection->isConnected() )
    {
       
$newId $this->getIncrementalId();

       
$newConnection->friendlySetPoolId$newId );

       
//
        // Add the connection to the pool.
        //
       
$this->connectionPool[$paramString][$newId] = &$newConnection;
       
$this->connectionLookup[$newId] = &$newConnection;

       
$newConnection->friendlySetUsed();
    }
    else
    {
       
$newConnection =
            &
$this->connectionFailureHandler$newConnection );
    }

   
$newObject $newConnection;

   
$newObject->jinnId $requestParams;
    if( 
is_array$requestParams ) )
    {
       
$newObject->jinnId null;
    }

    return 
$newObject;
}

getIncrementalId

private integer getIncrementalId ( )

Returns:
A unique integer for the current script runtime.

Used to enumerate pooled connections resources.

Source Code
function getIncrementalId()
{
    static 
$id 0;

   
$id++;

    return 
$id;
}

getParamString

private string getParamString
(
     array      $params
)


Parameters:
$params - A connection configuration array.

Returns:
The parameter structure converted to a string.

Creates a string based on the given connection configuration. This string can then be used to index identical pooled connections.

Source Code
function getParamString$params )
{
   
ksort$params );

   
$pString '';
    foreach( 
$params as $key => $value )
    {
       
$pString .= $key.'['.trim$value ).']-';
    }

    return 
substr$pString0, -);
}

getResource

public resource & getResource
(
     mixed      $params
)


Parameters:
$params - The name of a database or an explicity connection configuration structure. If the value is null then the default database is presumed.

Returns:
A MySQL database connection resource.

Used to retrieve a MySQL connection resource.

Notes
Warning:
USE AT YOUR OWN RISK  

Source Code
function &getResource$params=null )
{
   
$connection = &$this->getConnectionRef$params );

   
$paramString $this->getParamString$params );
   
$poolId $connection->friendlyGetPoolId();

    unset( 
$this->connectionPool[$paramString][$poolId] );
    unset( 
$this->connectionLookup[$poolId] );

   
$resource $connection->getResource();
   
$connection->friendlyClearResource();
   
$connection->free();

    return 
$resource;
}

lookupDB

private array lookupDB
(
     string      $name = default
)


Parameters:
$name - The name of the database configuration to lookup.

Returns:
The configuration structure for the requested database.

Attempts to find the database configuration having the requested name. This functions performs a recursive lookup such that if a name corresponds toa string value, then the string value is used as the next lookup name. If no entry is found then null is returned.

Source Code
function lookupDB$name=null )
{
    if( (string)
$name === '' )
    {
       
$name 'default';
    }

   
$databases =
        &
$this->getInterJinnVar'databases' );

    if( 
is_string$name )
        &&
        isset( 
$databases )
        &&
        isset( 
$databases[$name] ) )
    {
       
$dbParams $databases[$name];

        if( !
is_string$dbParams ) )
        {
            return 
$dbParams;
        }

        return 
$this->lookupDB$dbParams );
    }

    return 
null;
}