UniDB - MySQL, PostgreSQL, SQLiteFork on Github

 

Introduction

UniDB is a set of classes that provide a unified interface to connect and work with MySQL, PostgreSQL and SQLite databases. Without knowing the interals of either database server, you can use the same codebase to connect to the server, fetch data and iterate over it in your application. UniDB handles all the database specific commands and stuff underneath, so you don't need to worry about the data being different when accessing either database server. Other than the usual data access functionality, UniDB also include a number of utilities functions for each database, allowing you to work more easily with the database of your choice you choose for your application.

 

Requirements

UniDB requires PHP version 5.3+.

For the code to work, you will need to make sure proper extensions for the database clients are enabled in your PHP configuration.

Database support matrix is as follows:

  • MySQL: Version 4.0+ (including version 5)
  • PostgreSQL: Version 9.0+
  • SQLite: Version 2+

 

Required files

To start using UniDB, copy the files from the 'classes' folder inside this package anywhere you like.

Once you have copied these files to a folder of your choice, you are ready to use the UniDB class.

 

Code Samples

Basic Usage

The following is the simplest form of using UniDB in your PHP application:

<?php
  require( "classes/unidb.php" );
  $db = new UniDB( 'mysql5' );
  $db->connect( 'localhost', 'username', 'password' );
  $db->query( 'SELECT * from person' );
  while( $row = $db->fetch_row() ) {
  	echo 'Person Name: ' . $row['Name'];
  }
  $db->disconnect();
?>

Connecting to a particular Database Server

The server type should be specified in the UniDB class constructor when you create new objects:

You can specify either one of these as argument:

  • 'mysql4': If database server is MySQL version 4.0
  • 'mysql5': If MySQL database server version is 5.0 and above
  • 'mysqli': If MySQL database server version is 5.0 and above (requires 'mysqli' extension to be enabled in your PHP installtion)
  • 'pgsql': If database server is running PostgreSQL version 9.0 or above
  • 'sqlite': If you want to us SQLite databases in your application

Note: Since SQLite databases are portable and do not require a server, you should create a folder for your SQLite databases and specify it's path in the UniDB connect() method as argument, instead of host address.

Using PDO drivers

In order to use the PHP PDO extensions, you need to specify a second argument to the constructor for UniDB.

Currently the only option for this parameter is 'pdo', which makes UniDB use PDO drivers for the database instead of regular functions.

<?php
  require( "classes/unidb.php" );
  $db = new UniDB( 'mysql5', 'pdo' ); // note the second parameter
  $db->connect( 'localhost', 'username', 'password' );
  ...
  // rest of the code remains same for other method calls
?>
Note: Due to limitations of the PDO drivers in PHP, the num_rows() method in UniDB class always returns 0.
Unfortunately I could not find a nice workaround for that, so you are free to modify the code for pdo related functionality if you need num_rows() to work correctly.
There are a few implementations of this on the web. but none general in nature, so I have not included any in my class.
				

CRUD operations

To perform basic CRUD operations on your database, you can use code sample below:

<?php
  require( "classes/unidb.php" );
  $db = new UniDB( 'mysql5' );
  $db->connect( 'localhost', 'username', 'password' );

  // insert a new record
  $db->insert( 'person', array( 'Name' => 'John Doe', 'Dept_id' => 10 ) );

  // update an existing record
  $db->update( 'person', array( 'Name' => 'John Doe', 'Dept_id' => 10 ), "WHERE id = 10" );

  // delete an existing record
  $db->delete( 'person', "WHERE id = 10" );

  $db->disconnect();
?>

Multiple Queries

Sometimes it is desired to run additional queries within a fetch loop. UniDB provides a simple way to do this. See the sample below:

<?php
  require( "classes/unidb.php" );
  $db = new UniDB( 'mysql5' );
  $db->connect( 'localhost', 'username', 'password' );

  $db->query( 'SELECT * from person' );
  while( $row = $db->fetch_row() ) {
  	// run another query on the same db object
  	// notice the separate 'stack' argument to distinguish it from the main query
  	$db->query( 'SELECT * from dept WHERE dept_id = ' . $row['Dept_id'], '_dept' );
  	while( $row2 = $db->fetch_row( '_dept' ) ) {
  		echo 'Department Name: ' . $row2['Name'];
  }

  $db->disconnect();
?>
Note: You can run as many queries on a single object in parallel as you want, you only need to provide a separate string identifier for each query.
 

UniDB API methods

Method Description
$db = new UniDB($driver, $interface) Create a new UniDB object. You can create more that one objects if desired.
$driver: Type of driver to connect to the specific database/server. See above for the list of valid driver names.
$interface: if the value of this parameter is 'pdo', then UniDB uses PDO drivers (see example code above)
$connect($ip, $user = '', $password = '', $db = '') Connect to the database/server using the provided credentials. Returns TRUE on success, FALSE on failure.
$ip: For MySQL and PostgreSQL, it is the database server address (can include the port using a colon)
    For SQLite database, it is the complete path to the folder where SQLite databases are stored/to be created.
$user: Username to connect to the database
$password: Password for the database user
$db: Database name, if you want to select the database in the same function call.
SQLite does not require userid and password. You can either skip the two parameters, or provide empty values for them.
$db->disconnect() Closes the database/server connection.
$db->get_features() Returns the list of database objects supported by the database/server.
A sample return value from a SQLite database maybe as follows:
array(
  'views' => TRUE,
  'functions' => FALSE,
  'procedures' => FALSE,
  'triggers' => TRUE,
  'schemas' => FALSE,
  'sequences' => FALSE,
  'events' => FALSE					
)
$db->select_db($db) Selects the database provided as an argument. All further operations take place on that database. $db: Name of the database to be selected.
$db->create_db($db) Creates a new db. Does not select the new database. Use select_db() after create_db to select the newly created database.
$db: Name of the database to be created.
$db->query($sql, $stack=0) Runs an SQL query. Returns TRUE if the query is successful, FALSE otherwise.
$sql: SQL query to be executed (can be any valid query, not just SELECT).
$stack (optional): Unique identifier for this query. It is required when running multiple queries on the same UniDB object in a fetch loop. To fetch the results for a query with this unique stack identifier, use the same identifier with fetch_row() and num_rows() methods.
$db->insert($table, $values) Inserts new records in a table. Returns TRUE on success, FALSE otherwise.
$table: Name of the table in which the record is to be inserted.
$values: Array of key/value pairs, containing the field names as key and it's value as data.
$db->update($table, $values, $condition="") Updates record(s) in a table. Returns TRUE on success, FALSE otherwise.
$table: Name of the table in which the record is to be updated.
$values: Array of key/value pairs, containing the field names as key and it's value as data.
$condition (optional): Although optional, you would usually provide a condition for an update query, in the form of a WHERE clause. See above code sample for an example.
$db->delete($table, $condition) Deletes record(s) from a table. Returns TRUE on success, FALSE otherwise.
$table: Name of the table from which the record is to be deleted.
$condition: A condition for the delete query, in the form of a WHERE clause. See above code sample for an example.
$db->get_insert_id() Returns the INSERT ID for the last insert command run on the database.
Note: When using PDO with pgsql, this function always returns 0
$db->get_result($stack=0) Fetches the raw result set from the last query run on the db.
$stack (optional): Unique stack id for which the result is to be returned.
$db->fetch_row($stack=0, $type="") Retuns a single row from the result set based on the last SELECT query.
$stack (optional): Unique stack id for which the row is to be returned.
$type (optional): Type of keys you require in the row returned. By default the row contains both numeric and associative keys.
Valid values are:
'num': To return row as a numeric key/value pair.
'assoc': To return row as a associative key/value pair.
$db->fetch_row_num($num, $stack=0, $type="") Same a fetch_row(), except it returns the row at a particular index in the record set.
$num: Index of record in the result set which is to be returned.
$stack (optional): Unique stack id for which the row is to be returned.
$type (optional): Type of keys you require in the row returned. By default the row contains both numeric and associative keys.
$db->num_rows($stack=0) Returns the number of rows returned in a SELECT statement.
$stack (optional): Unique stack id for which the number of rows is to be returned.
$db->num_affected_rows($stack=0) Returns the number of affected rows in a table from the last insert/update/delete statement.
$stack (optional): Unique stack id for which the number of affected rows is to be returned.
$db->get_databases() Returns the list of databases on the server as an array.
For SQLite, the database names are the filenames found in the specified folder.
$db->get_tables() Returns the list of tables in the selected database as an array.
Note: Since PostgreSQL has schemas, the returned table names are prefixed by schema name, e.g. public.person, private.stats etc.
$db->get_views() Returns the list of views in the selected database as an array.
Note: This method only works on databases that actually support views. (e.g. MySQL 5).
$db->get_schemas() Returns the list of schemas in the selected database as an array.
Note: This method only works on databases that actually support schemas (e.g. PostgreSQL).
$db->get_triggers() Returns the list of triggers in the selected database as an array.
Note: This method only works on databases that actually support triggers. (e.g. MySQL 5).
$db->get_procedures() Returns the list of procedures in the selected database as an array.
Note: This method only works on databases that actually support procedures. (e.g. MySQL 5).
$db->get_functions() Returns the list of functions in the selected database as an array.
Note: This method only works on databases that actually support functions. (e.g. MySQL 5).
$db->get_sequences() Returns the list of sequences in the selected database as an array.
Note: This method only works on databases that actually support sequences. (e.g. PostgreSQL).
$db->truncate($table) Truncates (empties) the table name provided. Returns TRUE on success, FALSE otherwise.
$table: Name of table to be truncated.
$db->drop($name, $type) Drop the provided object name from the database. Returns TRUE on success, FALSE otherwise.
$name: Name of the table, view, procedure etc. to be deleted.
$type: Type of the object. Can be either 'table', 'view', 'procedure', 'function', 'trigger', 'schema', 'sequence'.
Examples:
  $db->drop( 'person', 'table' ); // drops the person table
  $db->drop( 'staff_managers', 'view' ); // drops the view named staff_managers
								
$db->escape($string) Returns the properly escaped string value for the database. Recommended if you use character data in your queries.
$string: String to be escaped.
$db->quote($string) Returns properly quoted string value for the database. Quoted values are usually the database objects names used in queries.
$string: String to be quoted.
$db->get_limit($count, $offset=0) Returns string representing the limit clause for the database. Useful when you want to display paginated views of your data in your webpage.
$count: Number of records to be applied in the limit clause.
$offset: Offset number of record to be applied in the limit clause.
$db->get_last_query() Returns the last SQL statement that was executed using the db object.
$db->get_last_error() Returns the error message that occured in the execution of the last query.
$db->get_query_time() Returns the time taken for the last query executed. The returned value is in milliseconds and ' ms' is automatically appended to it.
$db->log_error($str) This function is used internally by the database object to logs errors to the PHP error log. However, you can also use it if desired in your code.
$str: String to be appended to the PHP error log
$db->get_time() Gets the current time on the server in micro seconds. It is internally used to time the queries executed, but you can also use this method before and after queries, or other places in your code to benchmark a particular piece of code.
$db->set_option($option, $value) Sets an option for the db class.
$option: name of the option to set (string)
$value: value to set for this option
Options supported:
  'result_type' // the type of result set array indices (can be 'num', 'assoc' or 'both', default is 'both')
  'file_ext' // filename extension to be used in case of SQLite database (see demos/sqlite3.php for an example)
								
Example:
  $db->set_option('result_type', 'num'); // any result set fetched after this line will only contain numberic indices
  $db->set_option('result_type', 'assoc'); // any result set fetched after this line will only contain associative indices
  $db->set_option('result_type', 'both'); // result set will contain both types of indices
								
$db->set_options($options) Same as above, except that you provide an array of key/value pairs of options to set in one method call
$options: array of option names and their values
Example:
  $db->set_options(array('result_type'=>'num')); // please note that invalid option names will simply be ignored
  							
$db->expr($str) Returns raw representation of a value that can be used in CRUD queries. At the moment you can use either one of the three pre-defined expression strings, or any custom database expression.
$str: The raw database expression or one of the predefined string representations.
Pre-defined expressions:
  $db->expr( 'datetime' ); // returns 2014-05-08 20:05:05
  $db->expr( 'date' ); // returns 2014-05-08
  $db->expr( 'time' ); // returns 20:05:05
								
Other usage examples (see demos/expressions.php for running code):
  $db->expr( 'NOW()' ); // works only for MySQL databases
  $db->expr( 'MAX(user_id) + 1' ); // returns integer id greater than the highest user id in database
  $db->expr( 'COUNT(*)' ); // can be used in selected queries 
								
 

FAQ

Why is there no 'drop_db' method in API?

Drop database is a dangerous method and can cause critical data loss, therefore it is intentionally not included in the API.

Can I create multiple UniDB objects and connect to different databases on the same page?

Yes, you can create as many UniDB objects providing different driver type for each object for your use.

Can I use UniDB in place of an ORM in my application?

No, UniDB is not a replacement for ORM. However, you can modify your ORM code to use UniDB as the underlying database interface for the ORM.

I just get FALSE when I run a query on the database. How do I know what is wrong?

Use the get_last_error() method after a failed query to get the error message