NewsFeaturesDownloadsDevelopmentSupportAbout Us
PDb

PDb

From LifeType Wiki


Contents

[edit] Introduction

As of LifeType 1.1, the project dropped the dependency on ADOdb and instead chose to develop its own database abstraction layer, dubbed PDb (PDb stants for "Plog Database", as the name was chosen before the project name change)

The main reason for the change was ADOdb does a lot more than LifeType need, and it did not make any sense to carry all the extra overhead (in memory, in processing and in disk space requirements) of ADOdb while all what was needed was a tiny fraction from it. We considered the possibility of dropping the whole database abstraction layer and going with native calls with MySQL, but the development team is still hoping to add support for other database servers in the foreseeable future to LifeType. Therefore, we decided to implement our own lightweight database abstraction layer that would work as a drop-in replacement for ADOdb ("drop-in replacement" as far as LifeType is concerned)

PDb was designed from the ground up to keep the same interface as ADOdb and this means that all client classes that required certain methods or features from ADOdb will not notice any difference depending on whether they're running with PDb or ADOdb. However, PDb does not implement all the feature of ADOdb, but only those required in the core classes of LifeType. Features such as cursors, transactions and so on have not been implemented in PDb because they are not needed. Basic features such as different database drivers, result sets and even data dictionaries have been left in.

[edit] Available Drivers

Currently PDb only provides support for MySQL databases and result sets.

Data dictionaries are also supported for MySQL databases, allowing for easy modification of the database schema with a simple pseudo-language.

[edit] Using PDb

Classes that extend the Model class to provide data access functionality do not need to worry about PDb being used at the lowest layer. However, it might be necessary to open a connection to other databases in certain situations.

The main method used to initialize a driver is the static method PDb::getDriver($driverType) This method is a static factory method that returns an object of parent type PDbDriverBase implementing functionality specific to the database we have requested:

$db = PDb::getDriver( 'mysql' );

The only supported parameters as driverType are mysql.

At this point, we haven't opened the connection yet. We have only requested the PDb library to give us a driver of the requested type, so it's time to open the connection:

$db = PDb::getDriver( 'mysql' );
// host, username, password and dbname should come from elsewhere
$res = $db->PConnect( $host, $username, $password, $dbname );
if( !$res ) {
   die( "Could not connect!" );
}

The PConnect method, like in ADOdb, can be used to create a persistent connection to the given database server. If persistent connections are not allowed, NConnect can be used instead. The result of either PConnect and NConnect is true if successful or false otherwise (in line with ADOdb's implementation)

In order to execute a query and retrieve the results, we need to use the PDbDriverBase::Execute($query)' method and the PDbRecordSet base class that represents record sets.

$db = PDb::getDriver( 'mysql' );
// host, username, password and dbname should come from elsewhere
$res = $db->PConnect( $host, $username, $password, $dbname );
if( !$res ) {
   die( "Could not connect!" );
}

// execute the given query
$result = $db->Execute( "SELECT * FROM users" );
if( !$result ) {
   die( "Error executing query" );
}
// if successful, process the results
while( $row = $result->FetchRow()) {
   print_r( $row );
}

The Execute method takes a query as a parameter, without any further parameters. The result is null/false if there was an error or an object of type PdbResultSet. We can call PDbRecordSet::FetchRow() to fetch the row into an associative array much like ADOdb does (no possibility to load the data into an indexed array) and PDbRecordSet::RowCount() to get the number of rows if the query was a SELECT.

Finally, the connection can be closed via PdbDriverBase::Close()

[edit] Available methods

There is a full list of methods available in each one of the classes in section "Implementing additional drivers".

[edit] Data Dictionaries

Data dictionaries allow to easily manipulate and modify database schemas based on a description provided in a pseudo-language. Data dictionaries in PDb were almost literally taken from ADOdb and incorporated into PDb so they're 100% compatible with ADOdb. Even the factory function used to retrieve the correct data dictionary for a given driver has kept the same name.

There is enough information about ADOdb's data dictionaries in the ADOdb project page.

[edit] Implementing additional drivers

When creating additional drivers for PDb, there are two classes that need to be extended: PDbDriverBase as the base class providing the interface for drivers and PDbResultSet as the base class for result sets. Both classes should be placed in the class/pdb/drivers/ folder.

Before being able to call Pdb::getDriver("newdriver"), please modify the $_drivers array in the Pdb::getValidDrivers() to add a reference to your new driver. This is needed so that the PDb library recognizes your new driver as valid:

function getValidDrivers() {
 $_drivers = Array( "mysql"    => "PDbMySQLDriver",
                    "newdriver"=> "PDbMyNewDriver" );           
    
            return $_drivers;
        }

Now for each one of those two classes, there are a few methods that need to be implemented to provide the driver-specific code.

PDbDriverBase

The following methods need to be implemented in the new driver class extending PDbDriverBase. The exact implementation will vary from driver to driver but mos of the times there will be a one-to-one mapping between these methods and the native PHP functions used by PHP to acess this type of database server.

  • PDbDriverBase::PConnect: Opens a persistent connection to the database server.
  • PDbDriverBase::NConnect: Opens a non-persistent connection to the database.
  • PDbDriverBase::Connect($host,$user,$password,$db): Generic method to connect to the given database server. Depending on the implementation it may map onto PConnect or NConnect (depending on which one is the preferred one)
  • PDbDriverBase::Execute($query): Executes a query and returns null if there was an error executing the query or an object of parent type PdbResultSet.
  • PDbDriverBase::Close(): Closes the current connection.
  • PDbDriverBase::ErrorMsg(): Returns the last error message as provided by the RDBMS.
  • PDbDriverBase::Insert_ID(): Returns the value of the last AUTO_INCREMENT operation performed by the RDBMS, whenever supported (like in MySQL)
  • PDbDriverBase::Affected_Rows(): Returns the number of rows affected by the last INSERT, DELETE or UPDATE operation.
  • PDbDriverBase::isConnected(): Returns true if there is a connection open with the database server or false otherwise.
  • PDbDriverBase::setDriverOpt($key,$value): Allows PHP code to set driver specific parameters. This settings will depend on the driver and the base driver class does not provide default behaviour for these methods.

PDbRecordSet

The following methods need to be implemented in the new record set class wrapping around record sets for the new driver.

  • PDbRecordSet::FetchRow(): Fetches a row from the resulting query and maps it into an associative array.
  • PDbRecordSet::RowCount(): If the query was a SELECT query, returns the number of queries that were SELECTed.